/* Command register bits */ #define APDS9300_CMD BIT(7) /* Select command register. Must write as 1 */ #define APDS9300_WORD BIT(5) /* I2C write/read: if 1 word, if 0 byte */ #define APDS9300_CLEAR BIT(6) /* Interrupt clear. Clears pending interrupt */
/* Register set */ #define APDS9300_CONTROL 0x00 /* Control of basic functions */ #define APDS9300_THRESHLOWLOW 0x02 /* Low byte of low interrupt threshold */ #define APDS9300_THRESHHIGHLOW 0x04 /* Low byte of high interrupt threshold */ #define APDS9300_INTERRUPT 0x06 /* Interrupt control */ #define APDS9300_DATA0LOW 0x0c /* Low byte of ADC channel 0 */ #define APDS9300_DATA1LOW 0x0e /* Low byte of ADC channel 1 */
/* Power on/off value for APDS9300_CONTROL register */ #define APDS9300_POWER_ON 0x03 #define APDS9300_POWER_OFF 0x00
/* Interrupts */ #define APDS9300_INTR_ENABLE 0x10 /* Interrupt Persist Function: Any value outside of threshold range */ #define APDS9300_THRESH_INTR 0x01
#define APDS9300_THRESH_MAX 0xffff /* Max threshold value */
struct apds9300_data { struct i2c_client *client; struct mutex mutex; bool power_state; int thresh_low; int thresh_hi; bool intr_en;
};
cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
ret = i2c_smbus_write_byte_data(data->client,
APDS9300_CONTROL | APDS9300_CMD, cmd); if (ret) {
dev_err(&data->client->dev, "failed to set power state %d\n", state); return ret;
}
data->power_state = state;
return 0;
}
staticvoid apds9300_clear_intr(struct apds9300_data *data)
{ int ret;
ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD); if (ret < 0)
dev_err(&data->client->dev, "failed to clear interrupt\n");
}
staticint apds9300_chip_init(struct apds9300_data *data)
{ int ret;
/* Need to set power off to ensure that the chip is off */
ret = apds9300_set_power_state(data, 0); if (ret < 0) goto err; /* * Probe the chip. To do so we try to power up the device and then to * read back the 0x03 code
*/
ret = apds9300_set_power_state(data, 1); if (ret < 0) goto err;
ret = i2c_smbus_read_byte_data(data->client,
APDS9300_CONTROL | APDS9300_CMD); if (ret != APDS9300_POWER_ON) {
ret = -ENODEV; goto err;
} /* * Disable interrupt to ensure thai it is doesn't enable * i.e. after device soft reset
*/
ret = apds9300_set_intr_state(data, false); if (ret < 0) goto err;
return 0;
err:
dev_err(&data->client->dev, "failed to init the chip\n"); return ret;
}
staticint apds9300_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ int ch0, ch1, ret = -EINVAL; struct apds9300_data *data = iio_priv(indio_dev);
mutex_lock(&data->mutex); switch (chan->type) { case IIO_LIGHT:
ch0 = apds9300_get_adc_val(data, 0); if (ch0 < 0) {
ret = ch0; break;
}
ch1 = apds9300_get_adc_val(data, 1); if (ch1 < 0) {
ret = ch1; break;
}
*val = apds9300_calculate_lux(ch0, ch1);
ret = IIO_VAL_INT; break; case IIO_INTENSITY:
ret = apds9300_get_adc_val(data, chan->channel); if (ret < 0) break;
*val = ret;
ret = IIO_VAL_INT; break; default: break;
}
mutex_unlock(&data->mutex);
switch (dir) { case IIO_EV_DIR_RISING:
*val = data->thresh_hi; break; case IIO_EV_DIR_FALLING:
*val = data->thresh_low; break; default: return -EINVAL;
}
return IIO_VAL_INT;
}
staticint apds9300_write_thresh(struct iio_dev *indio_dev, conststruct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, int val, int val2)
{ struct apds9300_data *data = iio_priv(indio_dev); int ret;
mutex_lock(&data->mutex); if (dir == IIO_EV_DIR_RISING)
ret = apds9300_set_thresh_hi(data, val); else
ret = apds9300_set_thresh_low(data, val);
mutex_unlock(&data->mutex);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.