Lines Matching +full:chip +full:- +full:to +full:- +full:chip
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Copyright (c) 2016-2017 Brian Masney <[email protected]>
61 /* Per-device data */
91 * This structure is intentionally large to accommodate updates via
92 * sysfs. Sized to 11 = max 10 segments + 1 termination segment.
113 /* Index = (0 - 3) Used to validate the gain selection index */
125 static void tsl2583_defaults(struct tsl2583_chip *chip) in tsl2583_defaults() argument
131 chip->als_settings.als_time = 100; in tsl2583_defaults()
137 chip->als_settings.als_gain = 0; in tsl2583_defaults()
139 /* Default gain trim to account for aperture effects */ in tsl2583_defaults()
140 chip->als_settings.als_gain_trim = 1000; in tsl2583_defaults()
143 chip->als_settings.als_cal_target = 130; in tsl2583_defaults()
146 memcpy(chip->als_settings.als_device_lux, tsl2583_default_lux, in tsl2583_defaults()
157 * of ch1 value, to the ch0 value, is calculated. The array als_device_lux[]
158 * declared above is then scanned to find the first ratio value that is just
160 * the array are then used along with the time scale factor array values, to
171 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_get_lux() local
174 ret = i2c_smbus_read_byte_data(chip->client, TSL2583_CMD_REG); in tsl2583_get_lux()
176 dev_err(&chip->client->dev, "%s: failed to read CMD_REG register\n", in tsl2583_get_lux()
183 dev_err(&chip->client->dev, "%s: data not valid; returning last value\n", in tsl2583_get_lux()
185 ret = chip->als_cur_info.lux; /* return LAST VALUE */ in tsl2583_get_lux()
192 ret = i2c_smbus_read_byte_data(chip->client, reg); in tsl2583_get_lux()
194 dev_err(&chip->client->dev, "%s: failed to read register %x\n", in tsl2583_get_lux()
202 * Clear the pending interrupt status bit on the chip to allow the next in tsl2583_get_lux()
203 * integration cycle to start. This has to be done even though this in tsl2583_get_lux()
206 ret = i2c_smbus_write_byte(chip->client, in tsl2583_get_lux()
210 dev_err(&chip->client->dev, "%s: failed to clear the interrupt bit\n", in tsl2583_get_lux()
219 chip->als_cur_info.als_ch0 = ch0; in tsl2583_get_lux()
220 chip->als_cur_info.als_ch1 = ch1; in tsl2583_get_lux()
222 if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) in tsl2583_get_lux()
227 * The sensor appears to be in total darkness so set the in tsl2583_get_lux()
228 * calculated lux to 0 and return early to avoid a division by in tsl2583_get_lux()
232 chip->als_cur_info.lux = 0; in tsl2583_get_lux()
239 /* convert to unscaled lux using the pointer to the table */ in tsl2583_get_lux()
240 for (p = (struct tsl2583_lux *)chip->als_settings.als_device_lux; in tsl2583_get_lux()
241 p->ratio != 0 && p->ratio < ratio; p++) in tsl2583_get_lux()
244 if (p->ratio == 0) { in tsl2583_get_lux()
249 ch0lux = ((ch0 * p->ch0) + in tsl2583_get_lux()
250 (gainadj[chip->als_settings.als_gain].ch0 >> 1)) in tsl2583_get_lux()
251 / gainadj[chip->als_settings.als_gain].ch0; in tsl2583_get_lux()
252 ch1lux = ((ch1 * p->ch1) + in tsl2583_get_lux()
253 (gainadj[chip->als_settings.als_gain].ch1 >> 1)) in tsl2583_get_lux()
254 / gainadj[chip->als_settings.als_gain].ch1; in tsl2583_get_lux()
258 dev_dbg(&chip->client->dev, "%s: No Data - Returning 0\n", in tsl2583_get_lux()
261 chip->als_cur_info.lux = 0; in tsl2583_get_lux()
265 lux = ch0lux - ch1lux; in tsl2583_get_lux()
269 if (chip->als_time_scale == 0) in tsl2583_get_lux()
272 lux = (lux + (chip->als_time_scale >> 1)) / in tsl2583_get_lux()
273 chip->als_time_scale; in tsl2583_get_lux()
278 * so we need to shift right. in tsl2583_get_lux()
279 * User-specified gain provides a multiplier. in tsl2583_get_lux()
280 * Apply user-specified gain before shifting right to retain precision. in tsl2583_get_lux()
281 * Use 64 bits to avoid overflow on multiplication. in tsl2583_get_lux()
282 * Then go back to 32 bits before division to avoid using div_u64(). in tsl2583_get_lux()
285 lux64 = lux64 * chip->als_settings.als_gain_trim; in tsl2583_get_lux()
296 chip->als_cur_info.lux = lux; in tsl2583_get_lux()
305 * to derive actual lux).
310 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_als_calibrate() local
315 ret = i2c_smbus_read_byte_data(chip->client, in tsl2583_als_calibrate()
318 dev_err(&chip->client->dev, in tsl2583_als_calibrate()
319 "%s: failed to read from the CNTRL register\n", in tsl2583_als_calibrate()
326 dev_err(&chip->client->dev, in tsl2583_als_calibrate()
329 return -EINVAL; in tsl2583_als_calibrate()
331 dev_err(&chip->client->dev, in tsl2583_als_calibrate()
334 return -ENODATA; in tsl2583_als_calibrate()
339 dev_err(&chip->client->dev, "%s: failed to get lux\n", in tsl2583_als_calibrate()
346 dev_err(&chip->client->dev, in tsl2583_als_calibrate()
349 return -ENODATA; in tsl2583_als_calibrate()
352 gain_trim_val = (unsigned int)(((chip->als_settings.als_cal_target) in tsl2583_als_calibrate()
353 * chip->als_settings.als_gain_trim) / lux_val); in tsl2583_als_calibrate()
355 dev_err(&chip->client->dev, in tsl2583_als_calibrate()
358 return -ENODATA; in tsl2583_als_calibrate()
361 chip->als_settings.als_gain_trim = (int)gain_trim_val; in tsl2583_als_calibrate()
366 static int tsl2583_set_als_time(struct tsl2583_chip *chip) in tsl2583_set_als_time() argument
372 als_count = DIV_ROUND_CLOSEST(chip->als_settings.als_time * 100, 270); in tsl2583_set_als_time()
376 /* convert back to time (encompasses overrides) */ in tsl2583_set_als_time()
379 val = 256 - als_count; in tsl2583_set_als_time()
380 ret = i2c_smbus_write_byte_data(chip->client, in tsl2583_set_als_time()
384 dev_err(&chip->client->dev, "%s: failed to set the als time to %d\n", in tsl2583_set_als_time()
389 /* set chip struct re scaling and saturation */ in tsl2583_set_als_time()
390 chip->als_saturation = als_count * 922; /* 90% of full scale */ in tsl2583_set_als_time()
391 chip->als_time_scale = DIV_ROUND_CLOSEST(als_time, 50); in tsl2583_set_als_time()
396 static int tsl2583_set_als_gain(struct tsl2583_chip *chip) in tsl2583_set_als_gain() argument
401 ret = i2c_smbus_write_byte_data(chip->client, in tsl2583_set_als_gain()
403 chip->als_settings.als_gain); in tsl2583_set_als_gain()
405 dev_err(&chip->client->dev, in tsl2583_set_als_gain()
406 "%s: failed to set the gain to %d\n", __func__, in tsl2583_set_als_gain()
407 chip->als_settings.als_gain); in tsl2583_set_als_gain()
412 static int tsl2583_set_power_state(struct tsl2583_chip *chip, u8 state) in tsl2583_set_power_state() argument
416 ret = i2c_smbus_write_byte_data(chip->client, in tsl2583_set_power_state()
419 dev_err(&chip->client->dev, in tsl2583_set_power_state()
420 "%s: failed to set the power state to %d\n", __func__, in tsl2583_set_power_state()
432 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_chip_init_and_power_on() local
436 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON); in tsl2583_chip_init_and_power_on()
440 ret = i2c_smbus_write_byte_data(chip->client, in tsl2583_chip_init_and_power_on()
444 dev_err(&chip->client->dev, in tsl2583_chip_init_and_power_on()
445 "%s: failed to disable interrupts\n", __func__); in tsl2583_chip_init_and_power_on()
449 ret = tsl2583_set_als_time(chip); in tsl2583_chip_init_and_power_on()
453 ret = tsl2583_set_als_gain(chip); in tsl2583_chip_init_and_power_on()
459 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON | in tsl2583_chip_init_and_power_on()
474 struct tsl2583_chip *chip = iio_priv(indio_dev); in in_illuminance_input_target_show() local
477 mutex_lock(&chip->als_mutex); in in_illuminance_input_target_show()
478 ret = sprintf(buf, "%d\n", chip->als_settings.als_cal_target); in in_illuminance_input_target_show()
479 mutex_unlock(&chip->als_mutex); in in_illuminance_input_target_show()
489 struct tsl2583_chip *chip = iio_priv(indio_dev); in in_illuminance_input_target_store() local
493 return -EINVAL; in in_illuminance_input_target_store()
495 mutex_lock(&chip->als_mutex); in in_illuminance_input_target_store()
496 chip->als_settings.als_cal_target = value; in in_illuminance_input_target_store()
497 mutex_unlock(&chip->als_mutex); in in_illuminance_input_target_store()
507 struct tsl2583_chip *chip = iio_priv(indio_dev); in in_illuminance_calibrate_store() local
511 return -EINVAL; in in_illuminance_calibrate_store()
513 mutex_lock(&chip->als_mutex); in in_illuminance_calibrate_store()
521 mutex_unlock(&chip->als_mutex); in in_illuminance_calibrate_store()
531 struct tsl2583_chip *chip = iio_priv(indio_dev); in in_illuminance_lux_table_show() local
535 for (i = 0; i < ARRAY_SIZE(chip->als_settings.als_device_lux); i++) { in in_illuminance_lux_table_show()
537 chip->als_settings.als_device_lux[i].ratio, in in_illuminance_lux_table_show()
538 chip->als_settings.als_device_lux[i].ch0, in in_illuminance_lux_table_show()
539 chip->als_settings.als_device_lux[i].ch1); in in_illuminance_lux_table_show()
540 if (chip->als_settings.als_device_lux[i].ratio == 0) { in in_illuminance_lux_table_show()
545 offset--; in in_illuminance_lux_table_show()
560 struct tsl2583_chip *chip = iio_priv(indio_dev); in in_illuminance_lux_table_store() local
563 int ret = -EINVAL; in in_illuminance_lux_table_store()
566 mutex_lock(&chip->als_mutex); in in_illuminance_lux_table_store()
583 if ((value[n - 2] | value[n - 1] | value[n]) != 0) { in in_illuminance_lux_table_store()
589 memcpy(chip->als_settings.als_device_lux, &value[1], in in_illuminance_lux_table_store()
595 mutex_unlock(&chip->als_mutex); in in_illuminance_lux_table_store()
642 static int tsl2583_set_pm_runtime_busy(struct tsl2583_chip *chip, bool on) in tsl2583_set_pm_runtime_busy() argument
647 ret = pm_runtime_resume_and_get(&chip->client->dev); in tsl2583_set_pm_runtime_busy()
649 pm_runtime_mark_last_busy(&chip->client->dev); in tsl2583_set_pm_runtime_busy()
650 ret = pm_runtime_put_autosuspend(&chip->client->dev); in tsl2583_set_pm_runtime_busy()
660 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_read_raw() local
663 ret = tsl2583_set_pm_runtime_busy(chip, true); in tsl2583_read_raw()
667 mutex_lock(&chip->als_mutex); in tsl2583_read_raw()
669 ret = -EINVAL; in tsl2583_read_raw()
672 if (chan->type == IIO_LIGHT) { in tsl2583_read_raw()
682 * sensitive to both visible and infrared light, in tsl2583_read_raw()
684 * sensitive primarily to infrared light. in tsl2583_read_raw()
686 if (chan->channel2 == IIO_MOD_LIGHT_BOTH) in tsl2583_read_raw()
687 *val = chip->als_cur_info.als_ch0; in tsl2583_read_raw()
689 *val = chip->als_cur_info.als_ch1; in tsl2583_read_raw()
695 if (chan->type == IIO_LIGHT) { in tsl2583_read_raw()
705 if (chan->type == IIO_LIGHT) { in tsl2583_read_raw()
706 *val = chip->als_settings.als_gain_trim; in tsl2583_read_raw()
711 if (chan->type == IIO_LIGHT) { in tsl2583_read_raw()
712 *val = gainadj[chip->als_settings.als_gain].mean; in tsl2583_read_raw()
717 if (chan->type == IIO_LIGHT) { in tsl2583_read_raw()
719 *val2 = chip->als_settings.als_time; in tsl2583_read_raw()
728 mutex_unlock(&chip->als_mutex); in tsl2583_read_raw()
731 tsl2583_set_pm_runtime_busy(chip, false); in tsl2583_read_raw()
736 * Preserve the ret variable if the call to in tsl2583_read_raw()
738 * (if applicable) is returned to user space. in tsl2583_read_raw()
740 pm_ret = tsl2583_set_pm_runtime_busy(chip, false); in tsl2583_read_raw()
751 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_write_raw() local
754 ret = tsl2583_set_pm_runtime_busy(chip, true); in tsl2583_write_raw()
758 mutex_lock(&chip->als_mutex); in tsl2583_write_raw()
760 ret = -EINVAL; in tsl2583_write_raw()
763 if (chan->type == IIO_LIGHT) { in tsl2583_write_raw()
764 chip->als_settings.als_gain_trim = val; in tsl2583_write_raw()
769 if (chan->type == IIO_LIGHT) { in tsl2583_write_raw()
774 chip->als_settings.als_gain = i; in tsl2583_write_raw()
775 ret = tsl2583_set_als_gain(chip); in tsl2583_write_raw()
782 if (chan->type == IIO_LIGHT && !val && val2 >= 50 && in tsl2583_write_raw()
784 chip->als_settings.als_time = val2; in tsl2583_write_raw()
785 ret = tsl2583_set_als_time(chip); in tsl2583_write_raw()
792 mutex_unlock(&chip->als_mutex); in tsl2583_write_raw()
795 tsl2583_set_pm_runtime_busy(chip, false); in tsl2583_write_raw()
799 ret = tsl2583_set_pm_runtime_busy(chip, false); in tsl2583_write_raw()
815 struct tsl2583_chip *chip; in tsl2583_probe() local
818 if (!i2c_check_functionality(clientp->adapter, in tsl2583_probe()
820 dev_err(&clientp->dev, "%s: i2c smbus byte data functionality is unsupported\n", in tsl2583_probe()
822 return -EOPNOTSUPP; in tsl2583_probe()
825 indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip)); in tsl2583_probe()
827 return -ENOMEM; in tsl2583_probe()
829 chip = iio_priv(indio_dev); in tsl2583_probe()
830 chip->client = clientp; in tsl2583_probe()
833 mutex_init(&chip->als_mutex); in tsl2583_probe()
838 dev_err(&clientp->dev, in tsl2583_probe()
839 "%s: failed to read the chip ID register\n", __func__); in tsl2583_probe()
844 dev_err(&clientp->dev, "%s: received an unknown chip ID %x\n", in tsl2583_probe()
846 return -EINVAL; in tsl2583_probe()
849 indio_dev->info = &tsl2583_info; in tsl2583_probe()
850 indio_dev->channels = tsl2583_channels; in tsl2583_probe()
851 indio_dev->num_channels = ARRAY_SIZE(tsl2583_channels); in tsl2583_probe()
852 indio_dev->modes = INDIO_DIRECT_MODE; in tsl2583_probe()
853 indio_dev->name = chip->client->name; in tsl2583_probe()
855 pm_runtime_enable(&clientp->dev); in tsl2583_probe()
856 pm_runtime_set_autosuspend_delay(&clientp->dev, in tsl2583_probe()
858 pm_runtime_use_autosuspend(&clientp->dev); in tsl2583_probe()
862 dev_err(&clientp->dev, "%s: iio registration failed\n", in tsl2583_probe()
868 tsl2583_defaults(chip); in tsl2583_probe()
870 dev_info(&clientp->dev, "Light sensor found.\n"); in tsl2583_probe()
878 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_remove() local
882 pm_runtime_disable(&client->dev); in tsl2583_remove()
883 pm_runtime_set_suspended(&client->dev); in tsl2583_remove()
885 tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF); in tsl2583_remove()
891 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_suspend() local
894 mutex_lock(&chip->als_mutex); in tsl2583_suspend()
896 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF); in tsl2583_suspend()
898 mutex_unlock(&chip->als_mutex); in tsl2583_suspend()
906 struct tsl2583_chip *chip = iio_priv(indio_dev); in tsl2583_resume() local
909 mutex_lock(&chip->als_mutex); in tsl2583_resume()
913 mutex_unlock(&chip->als_mutex); in tsl2583_resume()