示例#1
0
static int isl29018_chip_init(struct i2c_client *client)
{
	struct isl29018_chip *chip = i2c_get_clientdata(client);
	bool status;
	int i;
	int new_adc_bit;
	unsigned int new_range;

	for (i = 0; i < ARRAY_SIZE(chip->reg_cache); i++) {
		chip->reg_cache[i] = 0;
	}

	/* set defaults */
	isl29018_write_data(client, ISL29018_REG_TEST,
		0x00, 0xFF, 0);
	isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1,
		0x00, 0xFF, 0);
	msleep(1);

	status = isl29018_set_range(client, chip->range, &new_range);
	if (status)
		status = isl29018_set_resolution(client, chip->adc_bit,
				&new_adc_bit);
	if (!status) {
		dev_err(&client->dev, "Init of isl29018 fails\n");
		return -ENODEV;
	}

	return 0;
}
示例#2
0
static int isl29018_read_sensor_input(struct i2c_client *client, int mode)
{
	int status;
	int lsb;
	int msb;

	/* Set mode */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1,
			mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT);
	if (status) {
		dev_err(&client->dev, "Error in setting operating mode\n");
		return status;
	}
	msleep(CONVERSION_TIME_MS);
	lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB);
	if (lsb < 0) {
		dev_err(&client->dev, "Error in reading LSB DATA\n");
		return lsb;
	}

	msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB);
	if (msb < 0) {
		dev_err(&client->dev, "Error in reading MSB DATA\n");
		return msb;
	}
	dev_vdbg(&client->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb);

	return (msb << 8) | lsb;
}
示例#3
0
static bool isl29018_set_range(struct i2c_client *client, unsigned long range,
		unsigned int *new_range)
{
	unsigned long supp_ranges[] = {1000, 4000, 16000, 64000};
	int i;

	for (i = 0; i < (ARRAY_SIZE(supp_ranges) -1); ++i) {
		if (range <= supp_ranges[i])
			break;
	}
	*new_range = (unsigned int)supp_ranges[i];
	return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
			i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT);
}
示例#4
0
static bool isl29018_set_resolution(struct i2c_client *client,
			unsigned long adcbit, unsigned int *conf_adc_bit)
{
	unsigned long supp_adcbit[] = {16, 12, 8, 4};
	int i;

	for (i = 0; i < (ARRAY_SIZE(supp_adcbit)); ++i) {
		if (adcbit == supp_adcbit[i])
			break;
	}
	*conf_adc_bit = (unsigned int)supp_adcbit[i];
	return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
			i, COMMANDII_RESOLUTION_MASK, COMMANDII_RESOLUTION_SHIFT);
}
static bool isl29018_set_current (struct i2c_client *client, unsigned long curr,
                unsigned int *new_current)
{
        unsigned long supp_currents[] = {12500, 25000, 50000, 100000};
        int i;

        for (i = 0; i < (ARRAY_SIZE(supp_currents) -1); ++i) {
                if (curr <= supp_currents[i])
                        break;
        }
        *new_current = (unsigned int)supp_currents[i];

        return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
                        i, COMMANDII_CURRSRC_MASK, COMMANDII_CURRSRC_SHIFT);
}
示例#6
0
static bool isl29018_read_lux(struct i2c_client *client, int *hb_lux,
		int *lb_lux)
{
	int lux_data;
	bool status = 0;
	int lsb = 0;
	int msb = 0;
	struct isl29018_chip *chip = i2c_get_clientdata(client);

	if(!chip->enable_ls || chip->suspend)
		return true;
	/* Set mode */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1,
			COMMMAND1_OPMODE_ALS_ONCE, COMMMAND1_OPMODE_MASK,
			COMMMAND1_OPMODE_SHIFT);
	if (!status) {
		dev_err(&client->dev, "Error in setting operating mode\n");
		return false;
	}
	msleep(CONVERSION_TIME_MS);
	if(!chip->enable_ls || chip->suspend)
		return true;
	lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB);
	if (lsb < 0) {
		dev_err(&client->dev, "Error in reading LSB DATA\n");
		return false;
	}

	msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB);
	if (msb < 0) {
		dev_err(&client->dev, "Error in reading MSB DATA\n");
		return false;
	}

	lux_data = ((msb << 8) | lsb);
	if (lux_data > 0) {
		*hb_lux = msb;
		*lb_lux = lsb;
		return true;
	}
	else {
		printk("isl29018_read_lux error / re-init chip... lux:%#x", lux_data);
		isl29018_chip_init(client);
	}
	return false;
}
示例#7
0
static int isl29018_set_range(struct i2c_client *client, unsigned long range,
		unsigned int *new_range)
{
	static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000};
	int i;

	for (i = 0; i < ARRAY_SIZE(supp_ranges); ++i) {
		if (range <= supp_ranges[i]) {
			*new_range = (unsigned int)supp_ranges[i];
			break;
		}
	}

	if (i >= ARRAY_SIZE(supp_ranges))
		return -EINVAL;

	return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
			i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT);
}
示例#8
0
static int isl29018_set_resolution(struct i2c_client *client,
			unsigned long adcbit, unsigned int *conf_adc_bit)
{
	static const unsigned long supp_adcbit[] = {16, 12, 8, 4};
	int i;

	for (i = 0; i < ARRAY_SIZE(supp_adcbit); ++i) {
		if (adcbit >= supp_adcbit[i]) {
			*conf_adc_bit = (unsigned int)supp_adcbit[i];
			break;
		}
	}

	if (i >= ARRAY_SIZE(supp_adcbit))
		return -EINVAL;

	return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
			i, COMMANDII_RESOLUTION_MASK,
			COMMANDII_RESOLUTION_SHIFT);
}
示例#9
0
static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme,
		int *near_ir)
{
	int status;
	int prox_data = -1;
	int ir_data = -1;

	/* Do proximity sensing with required scheme */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII,
			scheme, COMMANDII_SCHEME_MASK, COMMANDII_SCHEME_SHIFT);
	if (status) {
		dev_err(&client->dev, "Error in setting operating mode\n");
		return status;
	}

	prox_data = isl29018_read_sensor_input(client,
					COMMMAND1_OPMODE_PROX_ONCE);
	if (prox_data < 0)
		return prox_data;

	if (scheme == 1) {
		*near_ir = prox_data;
		return 0;
	}

	ir_data = isl29018_read_sensor_input(client,
				COMMMAND1_OPMODE_IR_ONCE);

	if (ir_data < 0)
		return ir_data;

	if (prox_data >= ir_data)
		*near_ir = prox_data - ir_data;
	else
		*near_ir = 0;

	return 0;
}
示例#10
0
static int isl29018_read_sensor_input(struct i2c_client *client, int mode)
{
	int status;
	int lux;

	/* Set mode */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1,
			mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT);
	if (status) {
		dev_err(&client->dev, "Error in setting operating mode\n");
		return status;
	}
	integration_wait(iio_priv(i2c_get_clientdata(client)));
	status = i2c_smbus_read_word_data(client, ISL29018_REG_ADD_DATA_LSB);
	if (status < 0) {
		dev_err(&client->dev, "Error in reading Lux DATA\n");
		return status;
	}

	lux = le16_to_cpu(status);
	dev_vdbg(&client->dev, "lux = %u\n", lux);

	return lux;
}
示例#11
0
static int isl29018_chip_init(struct i2c_client *client)
{
	struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client));
	int status;
	int new_adc_bit;
	unsigned int new_range;

	memset(chip->reg_cache, 0, sizeof(chip->reg_cache));

	/* Code added per Intersil Application Note 1534:
	 *     When VDD sinks to approximately 1.8V or below, some of
	 * the part's registers may change their state. When VDD
	 * recovers to 2.25V (or greater), the part may thus be in an
	 * unknown mode of operation. The user can return the part to
	 * a known mode of operation either by (a) setting VDD = 0V for
	 * 1 second or more and then powering back up with a slew rate
	 * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX
	 * conversions, clear the test registers, and then rewrite all
	 * registers to the desired values.
	 * ...
	 * FOR ISL29011, ISL29018, ISL29021, ISL29023
	 * 1. Write 0x00 to register 0x08 (TEST)
	 * 2. Write 0x00 to register 0x00 (CMD1)
	 * 3. Rewrite all registers to the desired values
	 *
	 * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says
	 * the same thing EXCEPT the data sheet asks for a 1ms delay after
	 * writing the CMD1 register.
	 */
	status = isl29018_write_data(client, ISL29018_REG_TEST, 0,
				ISL29018_TEST_MASK, ISL29018_TEST_SHIFT);
	if (status < 0) {
		dev_err(&client->dev, "Failed to clear isl29018 TEST reg."
					"(%d)\n", status);
		return status;
	}

	/* See Intersil AN1534 comments above.
	 * "Operating Mode" (COMMAND1) register is reprogrammed when
	 * data is read from the device.
	 */
	status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0,
				0xff, 0);
	if (status < 0) {
		dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg."
					"(%d)\n", status);
		return status;
	}

	msleep(1);	/* per data sheet, page 10 */

	/* set defaults */
	status = isl29018_set_range(client, chip->range, &new_range);
	if (status < 0) {
		dev_err(&client->dev, "Init of isl29018 fails\n");
		return status;
	}

	status = isl29018_set_resolution(client, chip->adc_bit,
						&new_adc_bit);

	return 0;
}