From 5fa77906549a35b2936257005ed641d07af1eb2c Mon Sep 17 00:00:00 2001 From: Praveen Bharathi Date: Wed, 1 Sep 2010 12:30:48 -0500 Subject: [PATCH] misc: max9635: Fix issues with LUX register read Modified driver to report lux every 2 secs. Also rearranged data/removed unused variables in header file. Change-Id: I3261a51497b2a55be735fbc73a6f15f7838b0b27 Signed-off-by: Praveen Bharathi --- drivers/misc/max9635.c | 124 +++++++++++++++------------------------- include/linux/max9635.h | 18 ++---- 2 files changed, 52 insertions(+), 90 deletions(-) diff --git a/drivers/misc/max9635.c b/drivers/misc/max9635.c index c58f4f02f622..9e724ee8bc99 100644 --- a/drivers/misc/max9635.c +++ b/drivers/misc/max9635.c @@ -190,63 +190,66 @@ static irqreturn_t max9635_irq_handler(int irq, void *dev) disable_irq_nosync(als_data->client->irq); schedule_delayed_work(&als_data->working_queue, 0); - return IRQ_HANDLED; } static int max9635_read_adj_als(struct max9635_data *als_data) { int ret; - int i; int lux = 0; u8 buf[2] = { MAX9635_ALS_DATA_H, 0 }; + u8 low_buf = MAX9635_ALS_DATA_L; + u8 high_buf = MAX9635_ALS_DATA_H; u8 exponent; u16 mantissa; - ret = max9635_read_reg(als_data, buf, 2); + ret = max9635_read_reg(als_data, &high_buf, 1); if (ret != 0) { - pr_err("%s:Unable to read interrupt register: %d\n", + pr_err("%s: Unable to read lux high byte register: %d\n", + __func__, ret); + return -1; + } + ret = max9635_read_reg(als_data, &low_buf, 1); + if (ret != 0) { + pr_err("%s: Unable to read lux low byte register: %d\n", __func__, ret); return -1; } - exponent = (buf[0] & 0xf0) >> 4; - mantissa = ((buf[0] & 0x0f) << 8) + buf[1]; - /* lux = 2^exponent * mantissa / 32 */ - lux = (mantissa << exponent) >> 5; - /* TO DO: Need to include lens loss coeffcient to achieve closer to - absolute lux value - if (als_data->als_pdata->lens_percent_t) - lux = ((10000 / als_data->als_pdata->lens_percent_t)* - (als_read_data)) / 100; */ - - for (i = 0; i < als_data->als_pdata->num_of_zones; i++) { - if ((lux <= als_data->max9635_zone_info[i].upper_threshold) - && (lux >= als_data->max9635_zone_info[i].lower_threshold)) { - if (max9635_debug & 1) - pr_info("%s:Setting next window to %i\n", - __func__, i); - - buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_L); - buf[1] = - als_data->als_pdata->als_lux_table[i].als_lower_threshold; - ret = max9635_write_reg(als_data, buf, 1); - if (ret != 0) { - pr_err("%s:Unable to write reg: %d\n", - __func__, buf[0]); - return -1; - } - buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_H); - buf[1] = - als_data->als_pdata->als_lux_table[i].als_higher_threshold; - ret = max9635_write_reg(als_data, buf, 1); - if (ret != 0) { - pr_err("%s:Unable to write reg: %d\n", - __func__, buf[0]); - return -1; - } - } + exponent = (high_buf & 0xf0) >> 4; + mantissa = ((high_buf & 0x0f) << 4) | (low_buf & 0x0f); + + lux = ((0001 << exponent) * mantissa) / 20; + if (max9635_debug & 1) + pr_info("exp = 0x%X, mant = 0x%X, lux = %d\n", + exponent, mantissa, lux); + + /* lux can be in the range of 0 to 208896, per maxim */ + if (lux == 0) + lux += 1; + if (lux == 208896) + lux -= 1; + + buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_L); + buf[1] = lux - 1; + ret = max9635_write_reg(als_data, buf, 1); + if (ret != 0) { + pr_err("%s:Unable to write reg: %d\n", __func__, buf[0]); + return -1; + } + if (max9635_debug & 1) + pr_err("lower threshold = %d\n", buf[1]); + + buf[0] = (AUTO_INCREMENT | MAX9635_ALS_THRESH_H); + buf[1] = lux + 1; + ret = max9635_write_reg(als_data, buf, 1); + if (ret != 0) { + pr_err("%s:Unable to write reg: %d\n", __func__, buf[0]); + return -1; } + if (max9635_debug & 1) + pr_err("upper threshold = %d\n", buf[1]); + if (max9635_debug & 1) pr_info("%s:Reporting LUX %d\n", __func__, lux); return lux; @@ -448,46 +451,13 @@ static DEVICE_ATTR(registers, 0644, max9635_registers_show, static void max9635_work_queue(struct work_struct *work) { - struct max9635_data *als_data = container_of((struct delayed_work *)work, - struct max9635_data, working_queue); + struct max9635_data *als_data = + container_of((struct delayed_work *)work, struct max9635_data, + working_queue); max9635_report_input(als_data); } -static void max9635_convert_zones(struct max9635_data *als_data) -{ - int i = 0; - int lux = 0; - u8 exponent; - u8 mantissa; - - /* Convert the byte to a lux value based - on the equation in the data sheet */ - for (i = 0; i < als_data->als_pdata->num_of_zones; i++) { - exponent = - (als_data->als_pdata->als_lux_table[i].als_lower_threshold & 0xf0) >> 4; - mantissa = - ((als_data->als_pdata->als_lux_table[i].als_lower_threshold & 0x0f) << 4); - /* lux = 2^exponent * mantissa / 32 */ - lux = (mantissa << exponent) >> 5; - als_data->max9635_zone_info[i].lower_threshold = lux; - - exponent = - (als_data->als_pdata->als_lux_table[i]. - als_higher_threshold & 0xf0) >> 4; - mantissa = - ((als_data->als_pdata->als_lux_table[i].als_higher_threshold & 0x0f) << 4) | 0x0f; - /* lux = 2^exponent * mantissa / 32 */ - lux = (mantissa << exponent) >> 5; - als_data->max9635_zone_info[i].upper_threshold = lux; - - pr_info("%s:Element %i Upper %d Lower %d\n", __func__, i, - als_data->max9635_zone_info[i].upper_threshold, - als_data->max9635_zone_info[i].lower_threshold); - } - return; -} - static int max9635_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -528,8 +498,6 @@ static int max9635_probe(struct i2c_client *client, input_set_capability(als_data->idev, EV_MSC, MSC_RAW); input_set_capability(als_data->idev, EV_LED, LED_MISC); - max9635_convert_zones(als_data); - error = misc_register(&max9635_misc_device); if (error < 0) { pr_err("%s: max9635 register failed\n", __func__); diff --git a/include/linux/max9635.h b/include/linux/max9635.h index aa514d8e89d7..4968a6835e67 100644 --- a/include/linux/max9635.h +++ b/include/linux/max9635.h @@ -23,19 +23,13 @@ #ifdef __KERNEL__ -struct max9635_als_zone_data { - int als_lower_threshold; - int als_higher_threshold; -}; - struct max9635_platform_data { - u8 configure; - u8 threshold_timer; - u8 def_low_threshold; - u8 def_high_threshold; - u32 lens_percent_t; - struct max9635_als_zone_data *als_lux_table; - u8 num_of_zones; + u8 configure; + u8 threshold_timer; + u8 def_low_threshold; + u8 def_high_threshold; + int (*power_on)(void); + int (*power_off)(void); }; #endif /* __KERNEL__ */ -- 2.34.1