struct tsl2x7x_als_info als_cur_info;
        struct tsl2x7x_settings settings;
        struct tsl2X7X_platform_data *pdata;
-       int als_time_scale;
+       int als_gain_time_scale;
        int als_saturation;
        int tsl2x7x_chip_status;
        u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG];
        struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE];
 };
 
-/* Different devices require different coefficents */
+/*
+ * Different devices require different coefficents, and these numbers were
+ * derived from the 'Lux Equation' section of the various device datasheets.
+ * All of these coefficients assume a Glass Attenuation (GA) factor of 1.
+ * The coefficients are multiplied by 1000 to avoid floating point operations.
+ * The two rows in each table correspond to the Lux1 and Lux2 equations from
+ * the datasheets.
+ */
 static const struct tsl2x7x_lux tsl2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
-       { 14461,   611,   1211 },
-       { 18540,   352,    623 },
-       {     0,     0,      0 },
+       { 53000, 106000 },
+       { 31800,  53000 },
+       { 0,          0 },
 };
 
 static const struct tsl2x7x_lux tmd2x71_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
-       { 11635,   115,    256 },
-       { 15536,    87,    179 },
-       {     0,     0,      0 },
+       { 24000,  48000 },
+       { 14400,  24000 },
+       { 0,          0 },
 };
 
 static const struct tsl2x7x_lux tsl2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
-       { 14013,   466,   917 },
-       { 18222,   310,   552 },
-       {     0,     0,     0 },
+       { 60000, 112200 },
+       { 37800,  60000 },
+       {     0,      0 },
 };
 
 static const struct tsl2x7x_lux tmd2x72_lux_table[TSL2X7X_DEF_LUX_TABLE_SZ] = {
-       { 13218,   130,   262 },
-       { 17592,   92,    169 },
-       {     0,     0,     0 },
+       { 20000,  35000 },
+       { 12600,  20000 },
+       {     0,      0 },
 };
 
 static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = {
  * @indio_dev: pointer to IIO device
  *
  * The raw ch0 and ch1 values of the ambient light sensed in the last
- * integration cycle are read from the device. Time scale factor array values
- * are adjusted based on the integration time. The raw values are multiplied
- * by a scale factor, and device gain is obtained using gain index. Limit
- * checks are done next, then the ratio of a multiple of ch1 value, to the
- * ch0 value, is calculated. Array tsl2x7x_device_lux[] is then scanned to
- * find the first ratio value that is just above the ratio we just calculated.
- * The ch0 and ch1 multiplier constants in the array are then used along with
- * the time scale factor array values, to calculate the lux.
+ * integration cycle are read from the device. The raw values are multiplied
+ * by a device-specific scale factor, and divided by the integration time and
+ * device gain. The code supports multiple lux equations through the lux table
+ * coefficients. A lux gain trim is applied to each lux equation, and then the
+ * maximum lux within the interval 0..65535 is selected.
  */
 static int tsl2x7x_get_lux(struct iio_dev *indio_dev)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
        struct tsl2x7x_lux *p;
-       u32 lux, ratio;
-       u64 lux64;
-       int ret;
+       int max_lux, ret;
+       bool overflow;
 
        mutex_lock(&chip->als_mutex);
 
                goto out_unlock;
        chip->als_cur_info.als_ch1 = ret;
 
-       if (chip->als_cur_info.als_ch0 >= chip->als_saturation ||
-           chip->als_cur_info.als_ch1 >= chip->als_saturation) {
-               lux = TSL2X7X_LUX_CALC_OVER_FLOW;
-               goto return_max;
+       if (chip->als_cur_info.als_ch0 >= chip->als_saturation) {
+               max_lux = TSL2X7X_LUX_CALC_OVER_FLOW;
+               goto update_struct_with_max_lux;
        }
 
        if (!chip->als_cur_info.als_ch0) {
                goto out_unlock;
        }
 
-       /* calculate ratio */
-       ratio = (chip->als_cur_info.als_ch1 << 15) / chip->als_cur_info.als_ch0;
-
-       /* convert to unscaled lux using the pointer to the table */
-       p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux;
-       while (p->ratio != 0 && p->ratio < ratio)
-               p++;
+       max_lux = 0;
+       overflow = false;
+       for (p = (struct tsl2x7x_lux *)chip->tsl2x7x_device_lux; p->ch0 != 0;
+            p++) {
+               int lux;
+
+               lux = ((chip->als_cur_info.als_ch0 * p->ch0) -
+                      (chip->als_cur_info.als_ch1 * p->ch1)) /
+                       chip->als_gain_time_scale;
+
+               /*
+                * The als_gain_trim can have a value within the range 250..4000
+                * and is a multiplier for the lux. A trim of 1000 makes no
+                * changes to the lux, less than 1000 scales it down, and
+                * greater than 1000 scales it up.
+                */
+               lux = (lux * chip->settings.als_gain_trim) / 1000;
+
+               if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) {
+                       overflow = true;
+                       continue;
+               }
 
-       if (p->ratio == 0) {
-               lux = 0;
-       } else {
-               lux = DIV_ROUND_UP(chip->als_cur_info.als_ch0 * p->ch0,
-                                  tsl2x7x_als_gain[chip->settings.als_gain]) -
-                     DIV_ROUND_UP(chip->als_cur_info.als_ch1 * p->ch1,
-                                  tsl2x7x_als_gain[chip->settings.als_gain]);
+               max_lux = max(max_lux, lux);
        }
 
-       /* adjust for active time scale */
-       if (chip->als_time_scale == 0)
-               lux = 0;
-       else
-               lux = (lux + (chip->als_time_scale >> 1)) /
-                       chip->als_time_scale;
-
-       /*
-        * adjust for active gain scale. The tsl2x7x_device_lux tables have a
-        * factor of 256 built-in. User-specified gain provides a multiplier.
-        * Apply user-specified gain before shifting right to retain precision.
-        * Use 64 bits to avoid overflow on multiplication. Then go back to
-        * 32 bits before division to avoid using div_u64().
-        */
-
-       lux64 = lux;
-       lux64 = lux64 * chip->settings.als_gain_trim;
-       lux64 >>= 8;
-       lux = lux64;
-       lux = (lux + 500) / 1000;
+       if (overflow && max_lux == 0)
+               max_lux = TSL2X7X_LUX_CALC_OVER_FLOW;
 
-       if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) /* check for overflow */
-               lux = TSL2X7X_LUX_CALC_OVER_FLOW;
-
-       /* Update the structure with the latest lux. */
-return_max:
-       chip->als_cur_info.lux = lux;
-       ret = lux;
+update_struct_with_max_lux:
+       chip->als_cur_info.lux = max_lux;
+       ret = max_lux;
 
 out_unlock:
        mutex_unlock(&chip->als_mutex);
                       sizeof(tsl2x7x_default_settings));
 
        /* Load up the proper lux table. */
-       if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0)
+       if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0)
                memcpy(chip->tsl2x7x_device_lux,
                       chip->pdata->platform_lux_table,
                       sizeof(chip->pdata->platform_lux_table));
 static int tsl2x7x_chip_on(struct iio_dev *indio_dev)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-       int ret, i, als_count, als_time;
+       int ret, i, als_count, als_time_us;
        u8 *dev_reg, reg_val;
 
        /* Non calculated parameters */
+       chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = chip->settings.als_time;
        chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = chip->settings.prox_time;
        chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = chip->settings.wait_time;
        chip->tsl2x7x_config[TSL2X7X_ALS_PRX_CONFIG] =
                return -EINVAL;
        }
 
-       /* determine als integration register */
-       als_count = (chip->settings.als_time * 100 + 135) / 270;
-       if (!als_count)
-               als_count = 1; /* ensure at least one cycle */
-
-       /* convert back to time (encompasses overrides) */
-       als_time = (als_count * 27 + 5) / 10;
-       chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count;
-
        /* Set the gain based on tsl2x7x_settings struct */
        chip->tsl2x7x_config[TSL2X7X_GAIN] =
                (chip->settings.als_gain & 0xFF) |
                (chip->settings.prox_diode << 4) |
                (chip->settings.prox_power << 6);
 
-       /* set chip struct re scaling and saturation */
-       chip->als_saturation = als_count * 922; /* 90% of full scale */
-       chip->als_time_scale = (als_time + 25) / 50;
+       /* set chip time scaling and saturation */
+       als_count = 256 - chip->settings.als_time;
+       als_time_us = als_count * 2720;
+       chip->als_saturation = als_count * 768; /* 75% of full scale */
+       chip->als_gain_time_scale = als_time_us *
+               tsl2x7x_als_gain[chip->settings.als_gain];
 
        /*
         * TSL2X7X Specific power-on / adc enable sequence
        int offset = 0;
 
        while (i < TSL2X7X_MAX_LUX_TABLE_SIZE) {
-               offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,%u,",
-                       chip->tsl2x7x_device_lux[i].ratio,
+               offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
                        chip->tsl2x7x_device_lux[i].ch0,
                        chip->tsl2x7x_device_lux[i].ch1);
-               if (chip->tsl2x7x_device_lux[i].ratio == 0) {
+               if (chip->tsl2x7x_device_lux[i].ch0 == 0) {
                        /*
                         * We just printed the first "0" entry.
                         * Now get rid of the extra "," and break.
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
-       int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 3 + 1];
+       int value[ARRAY_SIZE(chip->tsl2x7x_device_lux) * 2 + 1];
        int n, ret;
 
        get_options(buf, ARRAY_SIZE(value), value);
        /*
         * We now have an array of ints starting at value[1], and
         * enumerated by value[0].
-        * We expect each group of three ints is one table entry,
+        * We expect each group of two ints to be one table entry,
         * and the last table entry is all 0.
         */
        n = value[0];
-       if ((n % 3) || n < 6 ||
-           n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3))
+       if ((n % 2) || n < 4 ||
+           n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 2))
                return -EINVAL;
 
-       if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0)
+       if ((value[(n - 1)] | value[n]) != 0)
                return -EINVAL;
 
        if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) {
                ret = IIO_VAL_INT;
                break;
        case IIO_CHAN_INFO_INT_TIME:
-               *val = (TSL2X7X_MAX_TIMER_CNT - chip->settings.als_time) + 1;
-               *val2 = ((*val * TSL2X7X_MIN_ITIME) % 1000) / 1000;
+               *val = 0;
+               *val2 = (256 - chip->settings.als_time) * 2720;
                ret = IIO_VAL_INT_PLUS_MICRO;
                break;
        default:
                chip->settings.als_gain_trim = val;
                break;
        case IIO_CHAN_INFO_INT_TIME:
-               chip->settings.als_time =
-                       TSL2X7X_MAX_TIMER_CNT - (val2 / TSL2X7X_MIN_ITIME);
+               chip->settings.als_time = 256 - (val2 / 2720);
                break;
        default:
                return -EINVAL;