Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers/misc: driver for bh1770glc / sfh7770 ALS and proximity sensor

This is a driver for ROHM BH1770GLC and OSRAM SFH7770 combined ALS and
proximity sensor.

Interface is sysfs based. The driver uses interrupts to provide new data.
The driver supports pm_runtime and regulator frameworks.

See Documentation/misc-devices/bh1770glc.txt for details

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Samu Onkalo and committed by
Linus Torvalds
190420ab 4b068de9

+1477
+10
drivers/misc/Kconfig
··· 315 315 This driver can also be built as a module. If so, the module 316 316 will be called bh1780gli. 317 317 318 + config SENSORS_BH1770 319 + tristate "BH1770GLC / SFH7770 combined ALS - Proximity sensor" 320 + depends on I2C 321 + ---help--- 322 + Say Y here if you want to build a driver for BH1770GLC (ROHM) or 323 + SFH7770 (Osram) combined ambient light and proximity sensor chip. 324 + 325 + To compile this driver as a module, choose M here: the 326 + module will be called bh1770glc. If unsure, say N here. 327 + 318 328 config HMC6352 319 329 tristate "Honeywell HMC6352 compass" 320 330 depends on I2C
+1
drivers/misc/Makefile
··· 16 16 obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 17 17 obj-$(CONFIG_PHANTOM) += phantom.o 18 18 obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o 19 + obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o 19 20 obj-$(CONFIG_SGI_IOC4) += ioc4.o 20 21 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o 21 22 obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
+1413
drivers/misc/bh1770glc.c
··· 1 + /* 2 + * This file is part of the ROHM BH1770GLC / OSRAM SFH7770 sensor driver. 3 + * Chip is combined proximity and ambient light sensor. 4 + * 5 + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 6 + * 7 + * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * version 2 as published by the Free Software Foundation. 12 + * 13 + * This program is distributed in the hope that it will be useful, but 14 + * WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 + * General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 + * 02110-1301 USA 22 + * 23 + */ 24 + 25 + #include <linux/kernel.h> 26 + #include <linux/module.h> 27 + #include <linux/i2c.h> 28 + #include <linux/interrupt.h> 29 + #include <linux/mutex.h> 30 + #include <linux/i2c/bh1770glc.h> 31 + #include <linux/regulator/consumer.h> 32 + #include <linux/pm_runtime.h> 33 + #include <linux/workqueue.h> 34 + #include <linux/delay.h> 35 + #include <linux/wait.h> 36 + #include <linux/slab.h> 37 + 38 + #define BH1770_ALS_CONTROL 0x80 /* ALS operation mode control */ 39 + #define BH1770_PS_CONTROL 0x81 /* PS operation mode control */ 40 + #define BH1770_I_LED 0x82 /* active LED and LED1, LED2 current */ 41 + #define BH1770_I_LED3 0x83 /* LED3 current setting */ 42 + #define BH1770_ALS_PS_MEAS 0x84 /* Forced mode trigger */ 43 + #define BH1770_PS_MEAS_RATE 0x85 /* PS meas. rate at stand alone mode */ 44 + #define BH1770_ALS_MEAS_RATE 0x86 /* ALS meas. rate at stand alone mode */ 45 + #define BH1770_PART_ID 0x8a /* Part number and revision ID */ 46 + #define BH1770_MANUFACT_ID 0x8b /* Manufacturerer ID */ 47 + #define BH1770_ALS_DATA_0 0x8c /* ALS DATA low byte */ 48 + #define BH1770_ALS_DATA_1 0x8d /* ALS DATA high byte */ 49 + #define BH1770_ALS_PS_STATUS 0x8e /* Measurement data and int status */ 50 + #define BH1770_PS_DATA_LED1 0x8f /* PS data from LED1 */ 51 + #define BH1770_PS_DATA_LED2 0x90 /* PS data from LED2 */ 52 + #define BH1770_PS_DATA_LED3 0x91 /* PS data from LED3 */ 53 + #define BH1770_INTERRUPT 0x92 /* Interrupt setting */ 54 + #define BH1770_PS_TH_LED1 0x93 /* PS interrupt threshold for LED1 */ 55 + #define BH1770_PS_TH_LED2 0x94 /* PS interrupt threshold for LED2 */ 56 + #define BH1770_PS_TH_LED3 0x95 /* PS interrupt threshold for LED3 */ 57 + #define BH1770_ALS_TH_UP_0 0x96 /* ALS upper threshold low byte */ 58 + #define BH1770_ALS_TH_UP_1 0x97 /* ALS upper threshold high byte */ 59 + #define BH1770_ALS_TH_LOW_0 0x98 /* ALS lower threshold low byte */ 60 + #define BH1770_ALS_TH_LOW_1 0x99 /* ALS lower threshold high byte */ 61 + 62 + /* MANUFACT_ID */ 63 + #define BH1770_MANUFACT_ROHM 0x01 64 + #define BH1770_MANUFACT_OSRAM 0x03 65 + 66 + /* PART_ID */ 67 + #define BH1770_PART 0x90 68 + #define BH1770_PART_MASK 0xf0 69 + #define BH1770_REV_MASK 0x0f 70 + #define BH1770_REV_SHIFT 0 71 + #define BH1770_REV_0 0x00 72 + #define BH1770_REV_1 0x01 73 + 74 + /* Operating modes for both */ 75 + #define BH1770_STANDBY 0x00 76 + #define BH1770_FORCED 0x02 77 + #define BH1770_STANDALONE 0x03 78 + #define BH1770_SWRESET (0x01 << 2) 79 + 80 + #define BH1770_PS_TRIG_MEAS (1 << 0) 81 + #define BH1770_ALS_TRIG_MEAS (1 << 1) 82 + 83 + /* Interrupt control */ 84 + #define BH1770_INT_OUTPUT_MODE (1 << 3) /* 0 = latched */ 85 + #define BH1770_INT_POLARITY (1 << 2) /* 1 = active high */ 86 + #define BH1770_INT_ALS_ENA (1 << 1) 87 + #define BH1770_INT_PS_ENA (1 << 0) 88 + 89 + /* Interrupt status */ 90 + #define BH1770_INT_LED1_DATA (1 << 0) 91 + #define BH1770_INT_LED1_INT (1 << 1) 92 + #define BH1770_INT_LED2_DATA (1 << 2) 93 + #define BH1770_INT_LED2_INT (1 << 3) 94 + #define BH1770_INT_LED3_DATA (1 << 4) 95 + #define BH1770_INT_LED3_INT (1 << 5) 96 + #define BH1770_INT_LEDS_INT ((1 << 1) | (1 << 3) | (1 << 5)) 97 + #define BH1770_INT_ALS_DATA (1 << 6) 98 + #define BH1770_INT_ALS_INT (1 << 7) 99 + 100 + /* Led channels */ 101 + #define BH1770_LED1 0x00 102 + 103 + #define BH1770_DISABLE 0 104 + #define BH1770_ENABLE 1 105 + #define BH1770_PROX_CHANNELS 1 106 + 107 + #define BH1770_LUX_DEFAULT_RATE 1 /* Index to lux rate table */ 108 + #define BH1770_PROX_DEFAULT_RATE 1 /* Direct HW value =~ 50Hz */ 109 + #define BH1770_PROX_DEF_RATE_THRESH 6 /* Direct HW value =~ 5 Hz */ 110 + #define BH1770_STARTUP_DELAY 50 111 + #define BH1770_RESET_TIME 10 112 + #define BH1770_TIMEOUT 2100 /* Timeout in 2.1 seconds */ 113 + 114 + #define BH1770_LUX_RANGE 65535 115 + #define BH1770_PROX_RANGE 255 116 + #define BH1770_COEF_SCALER 1024 117 + #define BH1770_CALIB_SCALER 8192 118 + #define BH1770_LUX_NEUTRAL_CALIB_VALUE (1 * BH1770_CALIB_SCALER) 119 + #define BH1770_LUX_DEF_THRES 1000 120 + #define BH1770_PROX_DEF_THRES 70 121 + #define BH1770_PROX_DEF_ABS_THRES 100 122 + #define BH1770_DEFAULT_PERSISTENCE 10 123 + #define BH1770_PROX_MAX_PERSISTENCE 50 124 + #define BH1770_LUX_GA_SCALE 16384 125 + #define BH1770_LUX_CF_SCALE 2048 /* CF ChipFactor */ 126 + #define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE 127 + #define BH1770_LUX_CORR_SCALE 4096 128 + 129 + #define PROX_ABOVE_THRESHOLD 1 130 + #define PROX_BELOW_THRESHOLD 0 131 + 132 + #define PROX_IGNORE_LUX_LIMIT 500 133 + 134 + struct bh1770_chip { 135 + struct bh1770_platform_data *pdata; 136 + char chipname[10]; 137 + u8 revision; 138 + struct i2c_client *client; 139 + struct regulator_bulk_data regs[2]; 140 + struct mutex mutex; /* avoid parallel access */ 141 + wait_queue_head_t wait; 142 + 143 + bool int_mode_prox; 144 + bool int_mode_lux; 145 + struct delayed_work prox_work; 146 + u32 lux_cf; /* Chip specific factor */ 147 + u32 lux_ga; 148 + u32 lux_calib; 149 + int lux_rate_index; 150 + u32 lux_corr; 151 + u16 lux_data_raw; 152 + u16 lux_threshold_hi; 153 + u16 lux_threshold_lo; 154 + u16 lux_thres_hi_onchip; 155 + u16 lux_thres_lo_onchip; 156 + bool lux_wait_result; 157 + 158 + int prox_enable_count; 159 + u16 prox_coef; 160 + u16 prox_const; 161 + int prox_rate; 162 + int prox_rate_threshold; 163 + u8 prox_persistence; 164 + u8 prox_persistence_counter; 165 + u8 prox_data; 166 + u8 prox_threshold; 167 + u8 prox_threshold_hw; 168 + bool prox_force_update; 169 + u8 prox_abs_thres; 170 + u8 prox_led; 171 + }; 172 + 173 + static const char reg_vcc[] = "Vcc"; 174 + static const char reg_vleds[] = "Vleds"; 175 + 176 + /* 177 + * Supported stand alone rates in ms from chip data sheet 178 + * {10, 20, 30, 40, 70, 100, 200, 500, 1000, 2000}; 179 + */ 180 + static const s16 prox_rates_hz[] = {100, 50, 33, 25, 14, 10, 5, 2}; 181 + static const s16 prox_rates_ms[] = {10, 20, 30, 40, 70, 100, 200, 500}; 182 + 183 + /* Supported IR-led currents in mA */ 184 + static const u8 prox_curr_ma[] = {5, 10, 20, 50, 100, 150, 200}; 185 + 186 + /* 187 + * Supported stand alone rates in ms from chip data sheet 188 + * {100, 200, 500, 1000, 2000}; 189 + */ 190 + static const s16 lux_rates_hz[] = {10, 5, 2, 1, 0}; 191 + 192 + /* 193 + * interrupt control functions are called while keeping chip->mutex 194 + * excluding module probe / remove 195 + */ 196 + static inline int bh1770_lux_interrupt_control(struct bh1770_chip *chip, 197 + int lux) 198 + { 199 + chip->int_mode_lux = lux; 200 + /* Set interrupt modes, interrupt active low, latched */ 201 + return i2c_smbus_write_byte_data(chip->client, 202 + BH1770_INTERRUPT, 203 + (lux << 1) | chip->int_mode_prox); 204 + } 205 + 206 + static inline int bh1770_prox_interrupt_control(struct bh1770_chip *chip, 207 + int ps) 208 + { 209 + chip->int_mode_prox = ps; 210 + return i2c_smbus_write_byte_data(chip->client, 211 + BH1770_INTERRUPT, 212 + (chip->int_mode_lux << 1) | (ps << 0)); 213 + } 214 + 215 + /* chip->mutex is always kept here */ 216 + static int bh1770_lux_rate(struct bh1770_chip *chip, int rate_index) 217 + { 218 + /* sysfs may call this when the chip is powered off */ 219 + if (pm_runtime_suspended(&chip->client->dev)) 220 + return 0; 221 + 222 + /* Proper proximity response needs fastest lux rate (100ms) */ 223 + if (chip->prox_enable_count) 224 + rate_index = 0; 225 + 226 + return i2c_smbus_write_byte_data(chip->client, 227 + BH1770_ALS_MEAS_RATE, 228 + rate_index); 229 + } 230 + 231 + static int bh1770_prox_rate(struct bh1770_chip *chip, int mode) 232 + { 233 + int rate; 234 + 235 + rate = (mode == PROX_ABOVE_THRESHOLD) ? 236 + chip->prox_rate_threshold : chip->prox_rate; 237 + 238 + return i2c_smbus_write_byte_data(chip->client, 239 + BH1770_PS_MEAS_RATE, 240 + rate); 241 + } 242 + 243 + /* InfraredLED is controlled by the chip during proximity scanning */ 244 + static inline int bh1770_led_cfg(struct bh1770_chip *chip) 245 + { 246 + /* LED cfg, current for leds 1 and 2 */ 247 + return i2c_smbus_write_byte_data(chip->client, 248 + BH1770_I_LED, 249 + (BH1770_LED1 << 6) | 250 + (BH1770_LED_5mA << 3) | 251 + chip->prox_led); 252 + } 253 + 254 + /* 255 + * Following two functions converts raw ps values from HW to normalized 256 + * values. Purpose is to compensate differences between different sensor 257 + * versions and variants so that result means about the same between 258 + * versions. 259 + */ 260 + static inline u8 bh1770_psraw_to_adjusted(struct bh1770_chip *chip, u8 psraw) 261 + { 262 + u16 adjusted; 263 + adjusted = (u16)(((u32)(psraw + chip->prox_const) * chip->prox_coef) / 264 + BH1770_COEF_SCALER); 265 + if (adjusted > BH1770_PROX_RANGE) 266 + adjusted = BH1770_PROX_RANGE; 267 + return adjusted; 268 + } 269 + 270 + static inline u8 bh1770_psadjusted_to_raw(struct bh1770_chip *chip, u8 ps) 271 + { 272 + u16 raw; 273 + 274 + raw = (((u32)ps * BH1770_COEF_SCALER) / chip->prox_coef); 275 + if (raw > chip->prox_const) 276 + raw = raw - chip->prox_const; 277 + else 278 + raw = 0; 279 + return raw; 280 + } 281 + 282 + /* 283 + * Following two functions converts raw lux values from HW to normalized 284 + * values. Purpose is to compensate differences between different sensor 285 + * versions and variants so that result means about the same between 286 + * versions. Chip->mutex is kept when this is called. 287 + */ 288 + static int bh1770_prox_set_threshold(struct bh1770_chip *chip) 289 + { 290 + u8 tmp = 0; 291 + 292 + /* sysfs may call this when the chip is powered off */ 293 + if (pm_runtime_suspended(&chip->client->dev)) 294 + return 0; 295 + 296 + tmp = bh1770_psadjusted_to_raw(chip, chip->prox_threshold); 297 + chip->prox_threshold_hw = tmp; 298 + 299 + return i2c_smbus_write_byte_data(chip->client, BH1770_PS_TH_LED1, 300 + tmp); 301 + } 302 + 303 + static inline u16 bh1770_lux_raw_to_adjusted(struct bh1770_chip *chip, u16 raw) 304 + { 305 + u32 lux; 306 + lux = ((u32)raw * chip->lux_corr) / BH1770_LUX_CORR_SCALE; 307 + return min(lux, (u32)BH1770_LUX_RANGE); 308 + } 309 + 310 + static inline u16 bh1770_lux_adjusted_to_raw(struct bh1770_chip *chip, 311 + u16 adjusted) 312 + { 313 + return (u32)adjusted * BH1770_LUX_CORR_SCALE / chip->lux_corr; 314 + } 315 + 316 + /* chip->mutex is kept when this is called */ 317 + static int bh1770_lux_update_thresholds(struct bh1770_chip *chip, 318 + u16 threshold_hi, u16 threshold_lo) 319 + { 320 + u8 data[4]; 321 + int ret; 322 + 323 + /* sysfs may call this when the chip is powered off */ 324 + if (pm_runtime_suspended(&chip->client->dev)) 325 + return 0; 326 + 327 + /* 328 + * Compensate threshold values with the correction factors if not 329 + * set to minimum or maximum. 330 + * Min & max values disables interrupts. 331 + */ 332 + if (threshold_hi != BH1770_LUX_RANGE && threshold_hi != 0) 333 + threshold_hi = bh1770_lux_adjusted_to_raw(chip, threshold_hi); 334 + 335 + if (threshold_lo != BH1770_LUX_RANGE && threshold_lo != 0) 336 + threshold_lo = bh1770_lux_adjusted_to_raw(chip, threshold_lo); 337 + 338 + if (chip->lux_thres_hi_onchip == threshold_hi && 339 + chip->lux_thres_lo_onchip == threshold_lo) 340 + return 0; 341 + 342 + chip->lux_thres_hi_onchip = threshold_hi; 343 + chip->lux_thres_lo_onchip = threshold_lo; 344 + 345 + data[0] = threshold_hi; 346 + data[1] = threshold_hi >> 8; 347 + data[2] = threshold_lo; 348 + data[3] = threshold_lo >> 8; 349 + 350 + ret = i2c_smbus_write_i2c_block_data(chip->client, 351 + BH1770_ALS_TH_UP_0, 352 + ARRAY_SIZE(data), 353 + data); 354 + return ret; 355 + } 356 + 357 + static int bh1770_lux_get_result(struct bh1770_chip *chip) 358 + { 359 + u16 data; 360 + int ret; 361 + 362 + ret = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_DATA_0); 363 + if (ret < 0) 364 + return ret; 365 + 366 + data = ret & 0xff; 367 + ret = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_DATA_1); 368 + if (ret < 0) 369 + return ret; 370 + 371 + chip->lux_data_raw = data | ((ret & 0xff) << 8); 372 + 373 + return 0; 374 + } 375 + 376 + /* Calculate correction value which contains chip and device specific parts */ 377 + static u32 bh1770_get_corr_value(struct bh1770_chip *chip) 378 + { 379 + u32 tmp; 380 + /* Impact of glass attenuation correction */ 381 + tmp = (BH1770_LUX_CORR_SCALE * chip->lux_ga) / BH1770_LUX_GA_SCALE; 382 + /* Impact of chip factor correction */ 383 + tmp = (tmp * chip->lux_cf) / BH1770_LUX_CF_SCALE; 384 + /* Impact of Device specific calibration correction */ 385 + tmp = (tmp * chip->lux_calib) / BH1770_CALIB_SCALER; 386 + return tmp; 387 + } 388 + 389 + static int bh1770_lux_read_result(struct bh1770_chip *chip) 390 + { 391 + bh1770_lux_get_result(chip); 392 + return bh1770_lux_raw_to_adjusted(chip, chip->lux_data_raw); 393 + } 394 + 395 + /* 396 + * Chip on / off functions are called while keeping mutex except probe 397 + * or remove phase 398 + */ 399 + static int bh1770_chip_on(struct bh1770_chip *chip) 400 + { 401 + int ret = regulator_bulk_enable(ARRAY_SIZE(chip->regs), 402 + chip->regs); 403 + if (ret < 0) 404 + return ret; 405 + 406 + usleep_range(BH1770_STARTUP_DELAY, BH1770_STARTUP_DELAY * 2); 407 + 408 + /* Reset the chip */ 409 + i2c_smbus_write_byte_data(chip->client, BH1770_ALS_CONTROL, 410 + BH1770_SWRESET); 411 + usleep_range(BH1770_RESET_TIME, BH1770_RESET_TIME * 2); 412 + 413 + /* 414 + * ALS is started always since proximity needs als results 415 + * for realibility estimation. 416 + * Let's assume dark until the first ALS measurement is ready. 417 + */ 418 + chip->lux_data_raw = 0; 419 + chip->prox_data = 0; 420 + ret = i2c_smbus_write_byte_data(chip->client, 421 + BH1770_ALS_CONTROL, BH1770_STANDALONE); 422 + 423 + /* Assume reset defaults */ 424 + chip->lux_thres_hi_onchip = BH1770_LUX_RANGE; 425 + chip->lux_thres_lo_onchip = 0; 426 + 427 + return ret; 428 + } 429 + 430 + static void bh1770_chip_off(struct bh1770_chip *chip) 431 + { 432 + i2c_smbus_write_byte_data(chip->client, 433 + BH1770_INTERRUPT, BH1770_DISABLE); 434 + i2c_smbus_write_byte_data(chip->client, 435 + BH1770_ALS_CONTROL, BH1770_STANDBY); 436 + i2c_smbus_write_byte_data(chip->client, 437 + BH1770_PS_CONTROL, BH1770_STANDBY); 438 + regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); 439 + } 440 + 441 + /* chip->mutex is kept when this is called */ 442 + static int bh1770_prox_mode_control(struct bh1770_chip *chip) 443 + { 444 + if (chip->prox_enable_count) { 445 + chip->prox_force_update = true; /* Force immediate update */ 446 + 447 + bh1770_lux_rate(chip, chip->lux_rate_index); 448 + bh1770_prox_set_threshold(chip); 449 + bh1770_led_cfg(chip); 450 + bh1770_prox_rate(chip, PROX_BELOW_THRESHOLD); 451 + bh1770_prox_interrupt_control(chip, BH1770_ENABLE); 452 + i2c_smbus_write_byte_data(chip->client, 453 + BH1770_PS_CONTROL, BH1770_STANDALONE); 454 + } else { 455 + chip->prox_data = 0; 456 + bh1770_lux_rate(chip, chip->lux_rate_index); 457 + bh1770_prox_interrupt_control(chip, BH1770_DISABLE); 458 + i2c_smbus_write_byte_data(chip->client, 459 + BH1770_PS_CONTROL, BH1770_STANDBY); 460 + } 461 + return 0; 462 + } 463 + 464 + /* chip->mutex is kept when this is called */ 465 + static int bh1770_prox_read_result(struct bh1770_chip *chip) 466 + { 467 + int ret; 468 + bool above; 469 + u8 mode; 470 + 471 + ret = i2c_smbus_read_byte_data(chip->client, BH1770_PS_DATA_LED1); 472 + if (ret < 0) 473 + goto out; 474 + 475 + if (ret > chip->prox_threshold_hw) 476 + above = true; 477 + else 478 + above = false; 479 + 480 + /* 481 + * when ALS levels goes above limit, proximity result may be 482 + * false proximity. Thus ignore the result. With real proximity 483 + * there is a shadow causing low als levels. 484 + */ 485 + if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT) 486 + ret = 0; 487 + 488 + chip->prox_data = bh1770_psraw_to_adjusted(chip, ret); 489 + 490 + /* Strong proximity level or force mode requires immediate response */ 491 + if (chip->prox_data >= chip->prox_abs_thres || 492 + chip->prox_force_update) 493 + chip->prox_persistence_counter = chip->prox_persistence; 494 + 495 + chip->prox_force_update = false; 496 + 497 + /* Persistence filttering to reduce false proximity events */ 498 + if (likely(above)) { 499 + if (chip->prox_persistence_counter < chip->prox_persistence) { 500 + chip->prox_persistence_counter++; 501 + ret = -ENODATA; 502 + } else { 503 + mode = PROX_ABOVE_THRESHOLD; 504 + ret = 0; 505 + } 506 + } else { 507 + chip->prox_persistence_counter = 0; 508 + mode = PROX_BELOW_THRESHOLD; 509 + chip->prox_data = 0; 510 + ret = 0; 511 + } 512 + 513 + /* Set proximity detection rate based on above or below value */ 514 + if (ret == 0) { 515 + bh1770_prox_rate(chip, mode); 516 + sysfs_notify(&chip->client->dev.kobj, NULL, "prox0_raw"); 517 + } 518 + out: 519 + return ret; 520 + } 521 + 522 + static int bh1770_detect(struct bh1770_chip *chip) 523 + { 524 + struct i2c_client *client = chip->client; 525 + s32 ret; 526 + u8 manu, part; 527 + 528 + ret = i2c_smbus_read_byte_data(client, BH1770_MANUFACT_ID); 529 + if (ret < 0) 530 + goto error; 531 + manu = (u8)ret; 532 + 533 + ret = i2c_smbus_read_byte_data(client, BH1770_PART_ID); 534 + if (ret < 0) 535 + goto error; 536 + part = (u8)ret; 537 + 538 + chip->revision = (part & BH1770_REV_MASK) >> BH1770_REV_SHIFT; 539 + chip->prox_coef = BH1770_COEF_SCALER; 540 + chip->prox_const = 0; 541 + chip->lux_cf = BH1770_NEUTRAL_CF; 542 + 543 + if ((manu == BH1770_MANUFACT_ROHM) && 544 + ((part & BH1770_PART_MASK) == BH1770_PART)) { 545 + snprintf(chip->chipname, sizeof(chip->chipname), "BH1770GLC"); 546 + return 0; 547 + } 548 + 549 + if ((manu == BH1770_MANUFACT_OSRAM) && 550 + ((part & BH1770_PART_MASK) == BH1770_PART)) { 551 + snprintf(chip->chipname, sizeof(chip->chipname), "SFH7770"); 552 + /* Values selected by comparing different versions */ 553 + chip->prox_coef = 819; /* 0.8 * BH1770_COEF_SCALER */ 554 + chip->prox_const = 40; 555 + return 0; 556 + } 557 + 558 + ret = -ENODEV; 559 + error: 560 + dev_dbg(&client->dev, "BH1770 or SFH7770 not found\n"); 561 + 562 + return ret; 563 + } 564 + 565 + /* 566 + * This work is re-scheduled at every proximity interrupt. 567 + * If this work is running, it means that there hasn't been any 568 + * proximity interrupt in time. Situation is handled as no-proximity. 569 + * It would be nice to have low-threshold interrupt or interrupt 570 + * when measurement and hi-threshold are both 0. But neither of those exists. 571 + * This is a workaroud for missing HW feature. 572 + */ 573 + 574 + static void bh1770_prox_work(struct work_struct *work) 575 + { 576 + struct bh1770_chip *chip = 577 + container_of(work, struct bh1770_chip, prox_work.work); 578 + 579 + mutex_lock(&chip->mutex); 580 + bh1770_prox_read_result(chip); 581 + mutex_unlock(&chip->mutex); 582 + } 583 + 584 + /* This is threaded irq handler */ 585 + static irqreturn_t bh1770_irq(int irq, void *data) 586 + { 587 + struct bh1770_chip *chip = data; 588 + int status; 589 + int rate = 0; 590 + 591 + mutex_lock(&chip->mutex); 592 + status = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_PS_STATUS); 593 + 594 + /* Acknowledge interrupt by reading this register */ 595 + i2c_smbus_read_byte_data(chip->client, BH1770_INTERRUPT); 596 + 597 + /* 598 + * Check if there is fresh data available for als. 599 + * If this is the very first data, update thresholds after that. 600 + */ 601 + if (status & BH1770_INT_ALS_DATA) { 602 + bh1770_lux_get_result(chip); 603 + if (unlikely(chip->lux_wait_result)) { 604 + chip->lux_wait_result = false; 605 + wake_up(&chip->wait); 606 + bh1770_lux_update_thresholds(chip, 607 + chip->lux_threshold_hi, 608 + chip->lux_threshold_lo); 609 + } 610 + } 611 + 612 + /* Disable interrupt logic to guarantee acknowledgement */ 613 + i2c_smbus_write_byte_data(chip->client, BH1770_INTERRUPT, 614 + (0 << 1) | (0 << 0)); 615 + 616 + if ((status & BH1770_INT_ALS_INT)) 617 + sysfs_notify(&chip->client->dev.kobj, NULL, "lux0_input"); 618 + 619 + if (chip->int_mode_prox && (status & BH1770_INT_LEDS_INT)) { 620 + rate = prox_rates_ms[chip->prox_rate_threshold]; 621 + bh1770_prox_read_result(chip); 622 + } 623 + 624 + /* Re-enable interrupt logic */ 625 + i2c_smbus_write_byte_data(chip->client, BH1770_INTERRUPT, 626 + (chip->int_mode_lux << 1) | 627 + (chip->int_mode_prox << 0)); 628 + mutex_unlock(&chip->mutex); 629 + 630 + /* 631 + * Can't cancel work while keeping mutex since the work uses the 632 + * same mutex. 633 + */ 634 + if (rate) { 635 + /* 636 + * Simulate missing no-proximity interrupt 50ms after the 637 + * next expected interrupt time. 638 + */ 639 + cancel_delayed_work_sync(&chip->prox_work); 640 + schedule_delayed_work(&chip->prox_work, 641 + msecs_to_jiffies(rate + 50)); 642 + } 643 + return IRQ_HANDLED; 644 + } 645 + 646 + static ssize_t bh1770_power_state_store(struct device *dev, 647 + struct device_attribute *attr, 648 + const char *buf, size_t count) 649 + { 650 + struct bh1770_chip *chip = dev_get_drvdata(dev); 651 + unsigned long value; 652 + size_t ret; 653 + 654 + if (strict_strtoul(buf, 0, &value)) 655 + return -EINVAL; 656 + 657 + mutex_lock(&chip->mutex); 658 + if (value) { 659 + pm_runtime_get_sync(dev); 660 + 661 + ret = bh1770_lux_rate(chip, chip->lux_rate_index); 662 + ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE); 663 + 664 + if (ret < 0) { 665 + pm_runtime_put(dev); 666 + goto leave; 667 + } 668 + 669 + /* This causes interrupt after the next measurement cycle */ 670 + bh1770_lux_update_thresholds(chip, BH1770_LUX_DEF_THRES, 671 + BH1770_LUX_DEF_THRES); 672 + /* Inform that we are waiting for a result from ALS */ 673 + chip->lux_wait_result = true; 674 + bh1770_prox_mode_control(chip); 675 + } else if (!pm_runtime_suspended(dev)) { 676 + pm_runtime_put(dev); 677 + } 678 + ret = count; 679 + leave: 680 + mutex_unlock(&chip->mutex); 681 + return ret; 682 + } 683 + 684 + static ssize_t bh1770_power_state_show(struct device *dev, 685 + struct device_attribute *attr, char *buf) 686 + { 687 + return sprintf(buf, "%d\n", !pm_runtime_suspended(dev)); 688 + } 689 + 690 + static ssize_t bh1770_lux_result_show(struct device *dev, 691 + struct device_attribute *attr, char *buf) 692 + { 693 + struct bh1770_chip *chip = dev_get_drvdata(dev); 694 + ssize_t ret; 695 + long timeout; 696 + 697 + if (pm_runtime_suspended(dev)) 698 + return -EIO; /* Chip is not enabled at all */ 699 + 700 + timeout = wait_event_interruptible_timeout(chip->wait, 701 + !chip->lux_wait_result, 702 + msecs_to_jiffies(BH1770_TIMEOUT)); 703 + if (!timeout) 704 + return -EIO; 705 + 706 + mutex_lock(&chip->mutex); 707 + ret = sprintf(buf, "%d\n", bh1770_lux_read_result(chip)); 708 + mutex_unlock(&chip->mutex); 709 + 710 + return ret; 711 + } 712 + 713 + static ssize_t bh1770_lux_range_show(struct device *dev, 714 + struct device_attribute *attr, char *buf) 715 + { 716 + return sprintf(buf, "%d\n", BH1770_LUX_RANGE); 717 + } 718 + 719 + static ssize_t bh1770_prox_enable_store(struct device *dev, 720 + struct device_attribute *attr, 721 + const char *buf, size_t count) 722 + { 723 + struct bh1770_chip *chip = dev_get_drvdata(dev); 724 + unsigned long value; 725 + 726 + if (strict_strtoul(buf, 0, &value)) 727 + return -EINVAL; 728 + 729 + mutex_lock(&chip->mutex); 730 + /* Assume no proximity. Sensor will tell real state soon */ 731 + if (!chip->prox_enable_count) 732 + chip->prox_data = 0; 733 + 734 + if (value) 735 + chip->prox_enable_count++; 736 + else if (chip->prox_enable_count > 0) 737 + chip->prox_enable_count--; 738 + else 739 + goto leave; 740 + 741 + /* Run control only when chip is powered on */ 742 + if (!pm_runtime_suspended(dev)) 743 + bh1770_prox_mode_control(chip); 744 + leave: 745 + mutex_unlock(&chip->mutex); 746 + return count; 747 + } 748 + 749 + static ssize_t bh1770_prox_enable_show(struct device *dev, 750 + struct device_attribute *attr, char *buf) 751 + { 752 + struct bh1770_chip *chip = dev_get_drvdata(dev); 753 + ssize_t len; 754 + 755 + mutex_lock(&chip->mutex); 756 + len = sprintf(buf, "%d\n", chip->prox_enable_count); 757 + mutex_unlock(&chip->mutex); 758 + return len; 759 + } 760 + 761 + static ssize_t bh1770_prox_result_show(struct device *dev, 762 + struct device_attribute *attr, char *buf) 763 + { 764 + struct bh1770_chip *chip = dev_get_drvdata(dev); 765 + ssize_t ret; 766 + 767 + mutex_lock(&chip->mutex); 768 + if (chip->prox_enable_count && !pm_runtime_suspended(dev)) 769 + ret = sprintf(buf, "%d\n", chip->prox_data); 770 + else 771 + ret = -EIO; 772 + mutex_unlock(&chip->mutex); 773 + return ret; 774 + } 775 + 776 + static ssize_t bh1770_prox_range_show(struct device *dev, 777 + struct device_attribute *attr, char *buf) 778 + { 779 + return sprintf(buf, "%d\n", BH1770_PROX_RANGE); 780 + } 781 + 782 + static ssize_t bh1770_get_prox_rate_avail(struct device *dev, 783 + struct device_attribute *attr, char *buf) 784 + { 785 + int i; 786 + int pos = 0; 787 + for (i = 0; i < ARRAY_SIZE(prox_rates_hz); i++) 788 + pos += sprintf(buf + pos, "%d ", prox_rates_hz[i]); 789 + sprintf(buf + pos - 1, "\n"); 790 + return pos; 791 + } 792 + 793 + static ssize_t bh1770_get_prox_rate_above(struct device *dev, 794 + struct device_attribute *attr, char *buf) 795 + { 796 + struct bh1770_chip *chip = dev_get_drvdata(dev); 797 + return sprintf(buf, "%d\n", prox_rates_hz[chip->prox_rate_threshold]); 798 + } 799 + 800 + static ssize_t bh1770_get_prox_rate_below(struct device *dev, 801 + struct device_attribute *attr, char *buf) 802 + { 803 + struct bh1770_chip *chip = dev_get_drvdata(dev); 804 + return sprintf(buf, "%d\n", prox_rates_hz[chip->prox_rate]); 805 + } 806 + 807 + static int bh1770_prox_rate_validate(int rate) 808 + { 809 + int i; 810 + 811 + for (i = 0; i < ARRAY_SIZE(prox_rates_hz) - 1; i++) 812 + if (rate >= prox_rates_hz[i]) 813 + break; 814 + return i; 815 + } 816 + 817 + static ssize_t bh1770_set_prox_rate_above(struct device *dev, 818 + struct device_attribute *attr, 819 + const char *buf, size_t count) 820 + { 821 + struct bh1770_chip *chip = dev_get_drvdata(dev); 822 + unsigned long value; 823 + 824 + if (strict_strtoul(buf, 0, &value)) 825 + return -EINVAL; 826 + 827 + mutex_lock(&chip->mutex); 828 + chip->prox_rate_threshold = bh1770_prox_rate_validate(value); 829 + mutex_unlock(&chip->mutex); 830 + return count; 831 + } 832 + 833 + static ssize_t bh1770_set_prox_rate_below(struct device *dev, 834 + struct device_attribute *attr, 835 + const char *buf, size_t count) 836 + { 837 + struct bh1770_chip *chip = dev_get_drvdata(dev); 838 + unsigned long value; 839 + 840 + if (strict_strtoul(buf, 0, &value)) 841 + return -EINVAL; 842 + 843 + mutex_lock(&chip->mutex); 844 + chip->prox_rate = bh1770_prox_rate_validate(value); 845 + mutex_unlock(&chip->mutex); 846 + return count; 847 + } 848 + 849 + static ssize_t bh1770_get_prox_thres(struct device *dev, 850 + struct device_attribute *attr, char *buf) 851 + { 852 + struct bh1770_chip *chip = dev_get_drvdata(dev); 853 + return sprintf(buf, "%d\n", chip->prox_threshold); 854 + } 855 + 856 + static ssize_t bh1770_set_prox_thres(struct device *dev, 857 + struct device_attribute *attr, 858 + const char *buf, size_t count) 859 + { 860 + struct bh1770_chip *chip = dev_get_drvdata(dev); 861 + unsigned long value; 862 + int ret; 863 + 864 + if (strict_strtoul(buf, 0, &value)) 865 + return -EINVAL; 866 + if (value > BH1770_PROX_RANGE) 867 + return -EINVAL; 868 + 869 + mutex_lock(&chip->mutex); 870 + chip->prox_threshold = value; 871 + ret = bh1770_prox_set_threshold(chip); 872 + mutex_unlock(&chip->mutex); 873 + if (ret < 0) 874 + return ret; 875 + return count; 876 + } 877 + 878 + static ssize_t bh1770_prox_persistence_show(struct device *dev, 879 + struct device_attribute *attr, char *buf) 880 + { 881 + struct bh1770_chip *chip = dev_get_drvdata(dev); 882 + 883 + return sprintf(buf, "%u\n", chip->prox_persistence); 884 + } 885 + 886 + static ssize_t bh1770_prox_persistence_store(struct device *dev, 887 + struct device_attribute *attr, 888 + const char *buf, size_t len) 889 + { 890 + struct bh1770_chip *chip = dev_get_drvdata(dev); 891 + unsigned long value; 892 + 893 + if (strict_strtoul(buf, 0, &value)) 894 + return -EINVAL; 895 + 896 + if (value > BH1770_PROX_MAX_PERSISTENCE) 897 + return -EINVAL; 898 + 899 + chip->prox_persistence = value; 900 + 901 + return len; 902 + } 903 + 904 + static ssize_t bh1770_prox_abs_thres_show(struct device *dev, 905 + struct device_attribute *attr, char *buf) 906 + { 907 + struct bh1770_chip *chip = dev_get_drvdata(dev); 908 + return sprintf(buf, "%u\n", chip->prox_abs_thres); 909 + } 910 + 911 + static ssize_t bh1770_prox_abs_thres_store(struct device *dev, 912 + struct device_attribute *attr, 913 + const char *buf, size_t len) 914 + { 915 + struct bh1770_chip *chip = dev_get_drvdata(dev); 916 + unsigned long value; 917 + 918 + if (strict_strtoul(buf, 0, &value)) 919 + return -EINVAL; 920 + 921 + if (value > BH1770_PROX_RANGE) 922 + return -EINVAL; 923 + 924 + chip->prox_abs_thres = value; 925 + 926 + return len; 927 + } 928 + 929 + static ssize_t bh1770_chip_id_show(struct device *dev, 930 + struct device_attribute *attr, char *buf) 931 + { 932 + struct bh1770_chip *chip = dev_get_drvdata(dev); 933 + return sprintf(buf, "%s rev %d\n", chip->chipname, chip->revision); 934 + } 935 + 936 + static ssize_t bh1770_lux_calib_default_show(struct device *dev, 937 + struct device_attribute *attr, char *buf) 938 + { 939 + return sprintf(buf, "%u\n", BH1770_CALIB_SCALER); 940 + } 941 + 942 + static ssize_t bh1770_lux_calib_show(struct device *dev, 943 + struct device_attribute *attr, char *buf) 944 + { 945 + struct bh1770_chip *chip = dev_get_drvdata(dev); 946 + ssize_t len; 947 + 948 + mutex_lock(&chip->mutex); 949 + len = sprintf(buf, "%u\n", chip->lux_calib); 950 + mutex_unlock(&chip->mutex); 951 + return len; 952 + } 953 + 954 + static ssize_t bh1770_lux_calib_store(struct device *dev, 955 + struct device_attribute *attr, 956 + const char *buf, size_t len) 957 + { 958 + struct bh1770_chip *chip = dev_get_drvdata(dev); 959 + unsigned long value; 960 + u32 old_calib; 961 + u32 new_corr; 962 + 963 + if (strict_strtoul(buf, 0, &value)) 964 + return -EINVAL; 965 + 966 + mutex_lock(&chip->mutex); 967 + old_calib = chip->lux_calib; 968 + chip->lux_calib = value; 969 + new_corr = bh1770_get_corr_value(chip); 970 + if (new_corr == 0) { 971 + chip->lux_calib = old_calib; 972 + mutex_unlock(&chip->mutex); 973 + return -EINVAL; 974 + } 975 + chip->lux_corr = new_corr; 976 + /* Refresh thresholds on HW after changing correction value */ 977 + bh1770_lux_update_thresholds(chip, chip->lux_threshold_hi, 978 + chip->lux_threshold_lo); 979 + 980 + mutex_unlock(&chip->mutex); 981 + 982 + return len; 983 + } 984 + 985 + static ssize_t bh1770_get_lux_rate_avail(struct device *dev, 986 + struct device_attribute *attr, char *buf) 987 + { 988 + int i; 989 + int pos = 0; 990 + for (i = 0; i < ARRAY_SIZE(lux_rates_hz); i++) 991 + pos += sprintf(buf + pos, "%d ", lux_rates_hz[i]); 992 + sprintf(buf + pos - 1, "\n"); 993 + return pos; 994 + } 995 + 996 + static ssize_t bh1770_get_lux_rate(struct device *dev, 997 + struct device_attribute *attr, char *buf) 998 + { 999 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1000 + return sprintf(buf, "%d\n", lux_rates_hz[chip->lux_rate_index]); 1001 + } 1002 + 1003 + static ssize_t bh1770_set_lux_rate(struct device *dev, 1004 + struct device_attribute *attr, 1005 + const char *buf, size_t count) 1006 + { 1007 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1008 + unsigned long rate_hz; 1009 + int ret, i; 1010 + 1011 + if (strict_strtoul(buf, 0, &rate_hz)) 1012 + return -EINVAL; 1013 + 1014 + for (i = 0; i < ARRAY_SIZE(lux_rates_hz) - 1; i++) 1015 + if (rate_hz >= lux_rates_hz[i]) 1016 + break; 1017 + 1018 + mutex_lock(&chip->mutex); 1019 + chip->lux_rate_index = i; 1020 + ret = bh1770_lux_rate(chip, i); 1021 + mutex_unlock(&chip->mutex); 1022 + 1023 + if (ret < 0) 1024 + return ret; 1025 + 1026 + return count; 1027 + } 1028 + 1029 + static ssize_t bh1770_get_lux_thresh_above(struct device *dev, 1030 + struct device_attribute *attr, char *buf) 1031 + { 1032 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1033 + return sprintf(buf, "%d\n", chip->lux_threshold_hi); 1034 + } 1035 + 1036 + static ssize_t bh1770_get_lux_thresh_below(struct device *dev, 1037 + struct device_attribute *attr, char *buf) 1038 + { 1039 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1040 + return sprintf(buf, "%d\n", chip->lux_threshold_lo); 1041 + } 1042 + 1043 + static ssize_t bh1770_set_lux_thresh(struct bh1770_chip *chip, u16 *target, 1044 + const char *buf) 1045 + { 1046 + int ret = 0; 1047 + unsigned long thresh; 1048 + 1049 + if (strict_strtoul(buf, 0, &thresh)) 1050 + return -EINVAL; 1051 + 1052 + if (thresh > BH1770_LUX_RANGE) 1053 + return -EINVAL; 1054 + 1055 + mutex_lock(&chip->mutex); 1056 + *target = thresh; 1057 + /* 1058 + * Don't update values in HW if we are still waiting for 1059 + * first interrupt to come after device handle open call. 1060 + */ 1061 + if (!chip->lux_wait_result) 1062 + ret = bh1770_lux_update_thresholds(chip, 1063 + chip->lux_threshold_hi, 1064 + chip->lux_threshold_lo); 1065 + mutex_unlock(&chip->mutex); 1066 + return ret; 1067 + 1068 + } 1069 + 1070 + static ssize_t bh1770_set_lux_thresh_above(struct device *dev, 1071 + struct device_attribute *attr, 1072 + const char *buf, size_t len) 1073 + { 1074 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1075 + int ret = bh1770_set_lux_thresh(chip, &chip->lux_threshold_hi, buf); 1076 + if (ret < 0) 1077 + return ret; 1078 + return len; 1079 + } 1080 + 1081 + static ssize_t bh1770_set_lux_thresh_below(struct device *dev, 1082 + struct device_attribute *attr, 1083 + const char *buf, size_t len) 1084 + { 1085 + struct bh1770_chip *chip = dev_get_drvdata(dev); 1086 + int ret = bh1770_set_lux_thresh(chip, &chip->lux_threshold_lo, buf); 1087 + if (ret < 0) 1088 + return ret; 1089 + return len; 1090 + } 1091 + 1092 + static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, bh1770_prox_enable_show, 1093 + bh1770_prox_enable_store); 1094 + static DEVICE_ATTR(prox0_thresh_above1_value, S_IRUGO | S_IWUSR, 1095 + bh1770_prox_abs_thres_show, 1096 + bh1770_prox_abs_thres_store); 1097 + static DEVICE_ATTR(prox0_thresh_above0_value, S_IRUGO | S_IWUSR, 1098 + bh1770_get_prox_thres, 1099 + bh1770_set_prox_thres); 1100 + static DEVICE_ATTR(prox0_raw, S_IRUGO, bh1770_prox_result_show, NULL); 1101 + static DEVICE_ATTR(prox0_sensor_range, S_IRUGO, bh1770_prox_range_show, NULL); 1102 + static DEVICE_ATTR(prox0_thresh_above_count, S_IRUGO | S_IWUSR, 1103 + bh1770_prox_persistence_show, 1104 + bh1770_prox_persistence_store); 1105 + static DEVICE_ATTR(prox0_rate_above, S_IRUGO | S_IWUSR, 1106 + bh1770_get_prox_rate_above, 1107 + bh1770_set_prox_rate_above); 1108 + static DEVICE_ATTR(prox0_rate_below, S_IRUGO | S_IWUSR, 1109 + bh1770_get_prox_rate_below, 1110 + bh1770_set_prox_rate_below); 1111 + static DEVICE_ATTR(prox0_rate_avail, S_IRUGO, bh1770_get_prox_rate_avail, NULL); 1112 + 1113 + static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, bh1770_lux_calib_show, 1114 + bh1770_lux_calib_store); 1115 + static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO, 1116 + bh1770_lux_calib_default_show, 1117 + NULL); 1118 + static DEVICE_ATTR(lux0_input, S_IRUGO, bh1770_lux_result_show, NULL); 1119 + static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, bh1770_lux_range_show, NULL); 1120 + static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, bh1770_get_lux_rate, 1121 + bh1770_set_lux_rate); 1122 + static DEVICE_ATTR(lux0_rate_avail, S_IRUGO, bh1770_get_lux_rate_avail, NULL); 1123 + static DEVICE_ATTR(lux0_thresh_above_value, S_IRUGO | S_IWUSR, 1124 + bh1770_get_lux_thresh_above, 1125 + bh1770_set_lux_thresh_above); 1126 + static DEVICE_ATTR(lux0_thresh_below_value, S_IRUGO | S_IWUSR, 1127 + bh1770_get_lux_thresh_below, 1128 + bh1770_set_lux_thresh_below); 1129 + static DEVICE_ATTR(chip_id, S_IRUGO, bh1770_chip_id_show, NULL); 1130 + static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, bh1770_power_state_show, 1131 + bh1770_power_state_store); 1132 + 1133 + 1134 + static struct attribute *sysfs_attrs[] = { 1135 + &dev_attr_lux0_calibscale.attr, 1136 + &dev_attr_lux0_calibscale_default.attr, 1137 + &dev_attr_lux0_input.attr, 1138 + &dev_attr_lux0_sensor_range.attr, 1139 + &dev_attr_lux0_rate.attr, 1140 + &dev_attr_lux0_rate_avail.attr, 1141 + &dev_attr_lux0_thresh_above_value.attr, 1142 + &dev_attr_lux0_thresh_below_value.attr, 1143 + &dev_attr_prox0_raw.attr, 1144 + &dev_attr_prox0_sensor_range.attr, 1145 + &dev_attr_prox0_raw_en.attr, 1146 + &dev_attr_prox0_thresh_above_count.attr, 1147 + &dev_attr_prox0_rate_above.attr, 1148 + &dev_attr_prox0_rate_below.attr, 1149 + &dev_attr_prox0_rate_avail.attr, 1150 + &dev_attr_prox0_thresh_above0_value.attr, 1151 + &dev_attr_prox0_thresh_above1_value.attr, 1152 + &dev_attr_chip_id.attr, 1153 + &dev_attr_power_state.attr, 1154 + NULL 1155 + }; 1156 + 1157 + static struct attribute_group bh1770_attribute_group = { 1158 + .attrs = sysfs_attrs 1159 + }; 1160 + 1161 + static int __devinit bh1770_probe(struct i2c_client *client, 1162 + const struct i2c_device_id *id) 1163 + { 1164 + struct bh1770_chip *chip; 1165 + int err; 1166 + 1167 + chip = kzalloc(sizeof *chip, GFP_KERNEL); 1168 + if (!chip) 1169 + return -ENOMEM; 1170 + 1171 + i2c_set_clientdata(client, chip); 1172 + chip->client = client; 1173 + 1174 + mutex_init(&chip->mutex); 1175 + init_waitqueue_head(&chip->wait); 1176 + INIT_DELAYED_WORK(&chip->prox_work, bh1770_prox_work); 1177 + 1178 + if (client->dev.platform_data == NULL) { 1179 + dev_err(&client->dev, "platform data is mandatory\n"); 1180 + err = -EINVAL; 1181 + goto fail1; 1182 + } 1183 + 1184 + chip->pdata = client->dev.platform_data; 1185 + chip->lux_calib = BH1770_LUX_NEUTRAL_CALIB_VALUE; 1186 + chip->lux_rate_index = BH1770_LUX_DEFAULT_RATE; 1187 + chip->lux_threshold_lo = BH1770_LUX_DEF_THRES; 1188 + chip->lux_threshold_hi = BH1770_LUX_DEF_THRES; 1189 + 1190 + if (chip->pdata->glass_attenuation == 0) 1191 + chip->lux_ga = BH1770_NEUTRAL_GA; 1192 + else 1193 + chip->lux_ga = chip->pdata->glass_attenuation; 1194 + 1195 + chip->prox_threshold = BH1770_PROX_DEF_THRES; 1196 + chip->prox_led = chip->pdata->led_def_curr; 1197 + chip->prox_abs_thres = BH1770_PROX_DEF_ABS_THRES; 1198 + chip->prox_persistence = BH1770_DEFAULT_PERSISTENCE; 1199 + chip->prox_rate_threshold = BH1770_PROX_DEF_RATE_THRESH; 1200 + chip->prox_rate = BH1770_PROX_DEFAULT_RATE; 1201 + chip->prox_data = 0; 1202 + 1203 + chip->regs[0].supply = reg_vcc; 1204 + chip->regs[1].supply = reg_vleds; 1205 + 1206 + err = regulator_bulk_get(&client->dev, 1207 + ARRAY_SIZE(chip->regs), chip->regs); 1208 + if (err < 0) { 1209 + dev_err(&client->dev, "Cannot get regulators\n"); 1210 + goto fail1; 1211 + } 1212 + 1213 + err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), 1214 + chip->regs); 1215 + if (err < 0) { 1216 + dev_err(&client->dev, "Cannot enable regulators\n"); 1217 + goto fail2; 1218 + } 1219 + 1220 + usleep_range(BH1770_STARTUP_DELAY, BH1770_STARTUP_DELAY * 2); 1221 + err = bh1770_detect(chip); 1222 + if (err < 0) 1223 + goto fail3; 1224 + 1225 + /* Start chip */ 1226 + bh1770_chip_on(chip); 1227 + pm_runtime_set_active(&client->dev); 1228 + pm_runtime_enable(&client->dev); 1229 + 1230 + chip->lux_corr = bh1770_get_corr_value(chip); 1231 + if (chip->lux_corr == 0) { 1232 + dev_err(&client->dev, "Improper correction values\n"); 1233 + err = -EINVAL; 1234 + goto fail3; 1235 + } 1236 + 1237 + if (chip->pdata->setup_resources) { 1238 + err = chip->pdata->setup_resources(); 1239 + if (err) { 1240 + err = -EINVAL; 1241 + goto fail3; 1242 + } 1243 + } 1244 + 1245 + err = sysfs_create_group(&chip->client->dev.kobj, 1246 + &bh1770_attribute_group); 1247 + if (err < 0) { 1248 + dev_err(&chip->client->dev, "Sysfs registration failed\n"); 1249 + goto fail4; 1250 + } 1251 + 1252 + /* 1253 + * Chip needs level triggered interrupt to work. However, 1254 + * level triggering doesn't work always correctly with power 1255 + * management. Select both 1256 + */ 1257 + err = request_threaded_irq(client->irq, NULL, 1258 + bh1770_irq, 1259 + IRQF_TRIGGER_FALLING | IRQF_ONESHOT | 1260 + IRQF_TRIGGER_LOW, 1261 + "bh1770", chip); 1262 + if (err) { 1263 + dev_err(&client->dev, "could not get IRQ %d\n", 1264 + client->irq); 1265 + goto fail5; 1266 + } 1267 + regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); 1268 + return err; 1269 + fail5: 1270 + sysfs_remove_group(&chip->client->dev.kobj, 1271 + &bh1770_attribute_group); 1272 + fail4: 1273 + if (chip->pdata->release_resources) 1274 + chip->pdata->release_resources(); 1275 + fail3: 1276 + regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); 1277 + fail2: 1278 + regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs); 1279 + fail1: 1280 + kfree(chip); 1281 + return err; 1282 + } 1283 + 1284 + static int __devexit bh1770_remove(struct i2c_client *client) 1285 + { 1286 + struct bh1770_chip *chip = i2c_get_clientdata(client); 1287 + 1288 + free_irq(client->irq, chip); 1289 + 1290 + sysfs_remove_group(&chip->client->dev.kobj, 1291 + &bh1770_attribute_group); 1292 + 1293 + if (chip->pdata->release_resources) 1294 + chip->pdata->release_resources(); 1295 + 1296 + cancel_delayed_work_sync(&chip->prox_work); 1297 + 1298 + if (!pm_runtime_suspended(&client->dev)) 1299 + bh1770_chip_off(chip); 1300 + 1301 + pm_runtime_disable(&client->dev); 1302 + pm_runtime_set_suspended(&client->dev); 1303 + 1304 + regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs); 1305 + kfree(chip); 1306 + return 0; 1307 + } 1308 + 1309 + #ifdef CONFIG_PM 1310 + static int bh1770_suspend(struct device *dev) 1311 + { 1312 + struct i2c_client *client = container_of(dev, struct i2c_client, dev); 1313 + struct bh1770_chip *chip = i2c_get_clientdata(client); 1314 + 1315 + bh1770_chip_off(chip); 1316 + 1317 + return 0; 1318 + } 1319 + 1320 + static int bh1770_resume(struct device *dev) 1321 + { 1322 + struct i2c_client *client = container_of(dev, struct i2c_client, dev); 1323 + struct bh1770_chip *chip = i2c_get_clientdata(client); 1324 + int ret = 0; 1325 + 1326 + bh1770_chip_on(chip); 1327 + 1328 + if (!pm_runtime_suspended(dev)) { 1329 + /* 1330 + * If we were enabled at suspend time, it is expected 1331 + * everything works nice and smoothly 1332 + */ 1333 + ret = bh1770_lux_rate(chip, chip->lux_rate_index); 1334 + ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE); 1335 + 1336 + /* This causes interrupt after the next measurement cycle */ 1337 + bh1770_lux_update_thresholds(chip, BH1770_LUX_DEF_THRES, 1338 + BH1770_LUX_DEF_THRES); 1339 + /* Inform that we are waiting for a result from ALS */ 1340 + chip->lux_wait_result = true; 1341 + bh1770_prox_mode_control(chip); 1342 + } 1343 + return ret; 1344 + } 1345 + 1346 + #else 1347 + #define bh1770_suspend NULL 1348 + #define bh1770_shutdown NULL 1349 + #define bh1770_resume NULL 1350 + #endif 1351 + 1352 + #ifdef CONFIG_PM_RUNTIME 1353 + static int bh1770_runtime_suspend(struct device *dev) 1354 + { 1355 + struct i2c_client *client = container_of(dev, struct i2c_client, dev); 1356 + struct bh1770_chip *chip = i2c_get_clientdata(client); 1357 + 1358 + bh1770_chip_off(chip); 1359 + 1360 + return 0; 1361 + } 1362 + 1363 + static int bh1770_runtime_resume(struct device *dev) 1364 + { 1365 + struct i2c_client *client = container_of(dev, struct i2c_client, dev); 1366 + struct bh1770_chip *chip = i2c_get_clientdata(client); 1367 + 1368 + bh1770_chip_on(chip); 1369 + 1370 + return 0; 1371 + } 1372 + #endif 1373 + 1374 + static const struct i2c_device_id bh1770_id[] = { 1375 + {"bh1770glc", 0 }, 1376 + {"sfh7770", 0 }, 1377 + {} 1378 + }; 1379 + 1380 + MODULE_DEVICE_TABLE(i2c, bh1770_id); 1381 + 1382 + static const struct dev_pm_ops bh1770_pm_ops = { 1383 + SET_SYSTEM_SLEEP_PM_OPS(bh1770_suspend, bh1770_resume) 1384 + SET_RUNTIME_PM_OPS(bh1770_runtime_suspend, bh1770_runtime_resume, NULL) 1385 + }; 1386 + 1387 + static struct i2c_driver bh1770_driver = { 1388 + .driver = { 1389 + .name = "bh1770glc", 1390 + .owner = THIS_MODULE, 1391 + .pm = &bh1770_pm_ops, 1392 + }, 1393 + .probe = bh1770_probe, 1394 + .remove = __devexit_p(bh1770_remove), 1395 + .id_table = bh1770_id, 1396 + }; 1397 + 1398 + static int __init bh1770_init(void) 1399 + { 1400 + return i2c_add_driver(&bh1770_driver); 1401 + } 1402 + 1403 + static void __exit bh1770_exit(void) 1404 + { 1405 + i2c_del_driver(&bh1770_driver); 1406 + } 1407 + 1408 + MODULE_DESCRIPTION("BH1770GLC / SFH7770 combined ALS and proximity sensor"); 1409 + MODULE_AUTHOR("Samu Onkalo, Nokia Corporation"); 1410 + MODULE_LICENSE("GPL v2"); 1411 + 1412 + module_init(bh1770_init); 1413 + module_exit(bh1770_exit);
+53
include/linux/i2c/bh1770glc.h
··· 1 + /* 2 + * This file is part of the ROHM BH1770GLC / OSRAM SFH7770 sensor driver. 3 + * Chip is combined proximity and ambient light sensor. 4 + * 5 + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 6 + * 7 + * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * version 2 as published by the Free Software Foundation. 12 + * 13 + * This program is distributed in the hope that it will be useful, but 14 + * WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 + * General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public License 19 + * along with this program; if not, write to the Free Software 20 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 + * 02110-1301 USA 22 + * 23 + */ 24 + 25 + #ifndef __BH1770_H__ 26 + #define __BH1770_H__ 27 + 28 + /** 29 + * struct bh1770_platform_data - platform data for bh1770glc driver 30 + * @led_def_curr: IR led driving current. 31 + * @glass_attenuation: Attenuation factor for covering window. 32 + * @setup_resources: Call back for interrupt line setup function 33 + * @release_resources: Call back for interrupte line release function 34 + * 35 + * Example of glass attenuation: 16384 * 385 / 100 means attenuation factor 36 + * of 3.85. i.e. light_above_sensor = light_above_cover_window / 3.85 37 + */ 38 + 39 + struct bh1770_platform_data { 40 + #define BH1770_LED_5mA 0 41 + #define BH1770_LED_10mA 1 42 + #define BH1770_LED_20mA 2 43 + #define BH1770_LED_50mA 3 44 + #define BH1770_LED_100mA 4 45 + #define BH1770_LED_150mA 5 46 + #define BH1770_LED_200mA 6 47 + __u8 led_def_curr; 48 + #define BH1770_NEUTRAL_GA 16384 /* 16384 / 16384 = 1 */ 49 + __u32 glass_attenuation; 50 + int (*setup_resources)(void); 51 + int (*release_resources)(void); 52 + }; 53 + #endif