1 /* 2 * apds9802als.c - apds9802 ALS Driver 3 * 4 * Copyright (C) 2009 Intel Corp 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 21 * 22 */ 23 24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/slab.h> 27 #include <linux/i2c.h> 28 #include <linux/err.h> 29 #include <linux/delay.h> 30 #include <linux/mutex.h> 31 #include <linux/sysfs.h> 32 #include <linux/pm_runtime.h> 33 34 #define ALS_MIN_RANGE_VAL 1 35 #define ALS_MAX_RANGE_VAL 2 36 #define POWER_STA_ENABLE 1 37 #define POWER_STA_DISABLE 0 38 39 #define DRIVER_NAME "apds9802als" 40 41 struct als_data { 42 struct mutex mutex; 43 }; 44 45 static ssize_t als_sensing_range_show(struct device *dev, 46 struct device_attribute *attr, char *buf) 47 { 48 struct i2c_client *client = to_i2c_client(dev); 49 int val; 50 51 val = i2c_smbus_read_byte_data(client, 0x81); 52 if (val < 0) 53 return val; 54 if (val & 1) 55 return sprintf(buf, "4095\n"); 56 else 57 return sprintf(buf, "65535\n"); 58 } 59 60 static int als_wait_for_data_ready(struct device *dev) 61 { 62 struct i2c_client *client = to_i2c_client(dev); 63 int ret; 64 int retry = 10; 65 66 do { 67 msleep(30); 68 ret = i2c_smbus_read_byte_data(client, 0x86); 69 } while (!(ret & 0x80) && retry--); 70 71 if (retry < 0) { 72 dev_warn(dev, "timeout waiting for data ready\n"); 73 return -ETIMEDOUT; 74 } 75 76 return 0; 77 } 78 79 static ssize_t als_lux0_input_data_show(struct device *dev, 80 struct device_attribute *attr, char *buf) 81 { 82 struct i2c_client *client = to_i2c_client(dev); 83 struct als_data *data = i2c_get_clientdata(client); 84 int ret_val; 85 int temp; 86 87 /* Protect against parallel reads */ 88 pm_runtime_get_sync(dev); 89 mutex_lock(&data->mutex); 90 91 /* clear EOC interrupt status */ 92 i2c_smbus_write_byte(client, 0x40); 93 /* start measurement */ 94 temp = i2c_smbus_read_byte_data(client, 0x81); 95 i2c_smbus_write_byte_data(client, 0x81, temp | 0x08); 96 97 ret_val = als_wait_for_data_ready(dev); 98 if (ret_val < 0) 99 goto failed; 100 101 temp = i2c_smbus_read_byte_data(client, 0x8C); /* LSB data */ 102 if (temp < 0) { 103 ret_val = temp; 104 goto failed; 105 } 106 ret_val = i2c_smbus_read_byte_data(client, 0x8D); /* MSB data */ 107 if (ret_val < 0) 108 goto failed; 109 110 mutex_unlock(&data->mutex); 111 pm_runtime_put_sync(dev); 112 113 temp = (ret_val << 8) | temp; 114 return sprintf(buf, "%d\n", temp); 115 failed: 116 mutex_unlock(&data->mutex); 117 pm_runtime_put_sync(dev); 118 return ret_val; 119 } 120 121 static ssize_t als_sensing_range_store(struct device *dev, 122 struct device_attribute *attr, const char *buf, size_t count) 123 { 124 struct i2c_client *client = to_i2c_client(dev); 125 struct als_data *data = i2c_get_clientdata(client); 126 int ret_val; 127 unsigned long val; 128 129 if (strict_strtoul(buf, 10, &val)) 130 return -EINVAL; 131 132 if (val < 4096) 133 val = 1; 134 else if (val < 65536) 135 val = 2; 136 else 137 return -ERANGE; 138 139 pm_runtime_get_sync(dev); 140 141 /* Make sure nobody else reads/modifies/writes 0x81 while we 142 are active */ 143 mutex_lock(&data->mutex); 144 145 ret_val = i2c_smbus_read_byte_data(client, 0x81); 146 if (ret_val < 0) 147 goto fail; 148 149 /* Reset the bits before setting them */ 150 ret_val = ret_val & 0xFA; 151 152 if (val == 1) /* Setting detection range up to 4k LUX */ 153 ret_val = (ret_val | 0x01); 154 else /* Setting detection range up to 64k LUX*/ 155 ret_val = (ret_val | 0x00); 156 157 ret_val = i2c_smbus_write_byte_data(client, 0x81, ret_val); 158 159 if (ret_val >= 0) { 160 /* All OK */ 161 mutex_unlock(&data->mutex); 162 pm_runtime_put_sync(dev); 163 return count; 164 } 165 fail: 166 mutex_unlock(&data->mutex); 167 pm_runtime_put_sync(dev); 168 return ret_val; 169 } 170 171 static int als_set_power_state(struct i2c_client *client, bool on_off) 172 { 173 int ret_val; 174 struct als_data *data = i2c_get_clientdata(client); 175 176 mutex_lock(&data->mutex); 177 ret_val = i2c_smbus_read_byte_data(client, 0x80); 178 if (ret_val < 0) 179 goto fail; 180 if (on_off) 181 ret_val = ret_val | 0x01; 182 else 183 ret_val = ret_val & 0xFE; 184 ret_val = i2c_smbus_write_byte_data(client, 0x80, ret_val); 185 fail: 186 mutex_unlock(&data->mutex); 187 return ret_val; 188 } 189 190 static DEVICE_ATTR(lux0_sensor_range, S_IRUGO | S_IWUSR, 191 als_sensing_range_show, als_sensing_range_store); 192 static DEVICE_ATTR(lux0_input, S_IRUGO, als_lux0_input_data_show, NULL); 193 194 static struct attribute *mid_att_als[] = { 195 &dev_attr_lux0_sensor_range.attr, 196 &dev_attr_lux0_input.attr, 197 NULL 198 }; 199 200 static struct attribute_group m_als_gr = { 201 .name = "apds9802als", 202 .attrs = mid_att_als 203 }; 204 205 static int als_set_default_config(struct i2c_client *client) 206 { 207 int ret_val; 208 /* Write the command and then switch on */ 209 ret_val = i2c_smbus_write_byte_data(client, 0x80, 0x01); 210 if (ret_val < 0) { 211 dev_err(&client->dev, "failed default switch on write\n"); 212 return ret_val; 213 } 214 /* detection range: 1~64K Lux, maunal measurement */ 215 ret_val = i2c_smbus_write_byte_data(client, 0x81, 0x08); 216 if (ret_val < 0) 217 dev_err(&client->dev, "failed default LUX on write\n"); 218 219 /* We always get 0 for the 1st measurement after system power on, 220 * so make sure it is finished before user asks for data. 221 */ 222 als_wait_for_data_ready(&client->dev); 223 224 return ret_val; 225 } 226 227 static int apds9802als_probe(struct i2c_client *client, 228 const struct i2c_device_id *id) 229 { 230 int res; 231 struct als_data *data; 232 233 data = kzalloc(sizeof(struct als_data), GFP_KERNEL); 234 if (data == NULL) { 235 dev_err(&client->dev, "Memory allocation failed\n"); 236 return -ENOMEM; 237 } 238 i2c_set_clientdata(client, data); 239 res = sysfs_create_group(&client->dev.kobj, &m_als_gr); 240 if (res) { 241 dev_err(&client->dev, "device create file failed\n"); 242 goto als_error1; 243 } 244 dev_info(&client->dev, "ALS chip found\n"); 245 als_set_default_config(client); 246 mutex_init(&data->mutex); 247 248 pm_runtime_set_active(&client->dev); 249 pm_runtime_enable(&client->dev); 250 251 return res; 252 als_error1: 253 kfree(data); 254 return res; 255 } 256 257 static int apds9802als_remove(struct i2c_client *client) 258 { 259 struct als_data *data = i2c_get_clientdata(client); 260 261 pm_runtime_get_sync(&client->dev); 262 263 als_set_power_state(client, false); 264 sysfs_remove_group(&client->dev.kobj, &m_als_gr); 265 266 pm_runtime_disable(&client->dev); 267 pm_runtime_set_suspended(&client->dev); 268 pm_runtime_put_noidle(&client->dev); 269 270 kfree(data); 271 return 0; 272 } 273 274 #ifdef CONFIG_PM 275 static int apds9802als_suspend(struct i2c_client *client, pm_message_t mesg) 276 { 277 als_set_power_state(client, false); 278 return 0; 279 } 280 281 static int apds9802als_resume(struct i2c_client *client) 282 { 283 als_set_default_config(client); 284 return 0; 285 } 286 287 static int apds9802als_runtime_suspend(struct device *dev) 288 { 289 struct i2c_client *client = to_i2c_client(dev); 290 291 als_set_power_state(client, false); 292 return 0; 293 } 294 295 static int apds9802als_runtime_resume(struct device *dev) 296 { 297 struct i2c_client *client = to_i2c_client(dev); 298 299 als_set_power_state(client, true); 300 return 0; 301 } 302 303 static const struct dev_pm_ops apds9802als_pm_ops = { 304 .runtime_suspend = apds9802als_runtime_suspend, 305 .runtime_resume = apds9802als_runtime_resume, 306 }; 307 308 #define APDS9802ALS_PM_OPS (&apds9802als_pm_ops) 309 310 #else /* CONFIG_PM */ 311 #define apds9802als_suspend NULL 312 #define apds9802als_resume NULL 313 #define APDS9802ALS_PM_OPS NULL 314 #endif /* CONFIG_PM */ 315 316 static struct i2c_device_id apds9802als_id[] = { 317 { DRIVER_NAME, 0 }, 318 { } 319 }; 320 321 MODULE_DEVICE_TABLE(i2c, apds9802als_id); 322 323 static struct i2c_driver apds9802als_driver = { 324 .driver = { 325 .name = DRIVER_NAME, 326 .pm = APDS9802ALS_PM_OPS, 327 }, 328 .probe = apds9802als_probe, 329 .remove = apds9802als_remove, 330 .suspend = apds9802als_suspend, 331 .resume = apds9802als_resume, 332 .id_table = apds9802als_id, 333 }; 334 335 module_i2c_driver(apds9802als_driver); 336 337 MODULE_AUTHOR("Anantha Narayanan <Anantha.Narayanan@intel.com"); 338 MODULE_DESCRIPTION("Avago apds9802als ALS Driver"); 339 MODULE_LICENSE("GPL v2"); 340