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

iio: light sensor: Add SMBUS support to the tsl2563 driver.

This is so we can support it on x86 SMBUS adapters.

Since i2c adapters which do not provide an smbus_xfer interface fall
back to using their I2C master_xfer interface, all the i2c_master_send()
calls in this driver are changed to i2c_smbus_*() calls.
This will fail on an i2c adapter that implements a proper subset of
(SMBUS_BYTE | SMBUS_BYTE_DATA | SMBUS_WORD_DATA), but I do not see that
in any of our adapters today.

This results in a few wrapper functions that provide little additional
functionality, so remove them and call the smbus functions directly from
the general driver code.

Signed-off-by: Bryan Freed <bfreed@chromium.org>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Bryan Freed and committed by
Greg Kroah-Hartman
d9b42c01 9e4216fd

+45 -61
+45 -61
drivers/staging/iio/light/tsl2563.c
··· 137 137 u32 data1; 138 138 }; 139 139 140 - static int tsl2563_write(struct i2c_client *client, u8 reg, u8 value) 141 - { 142 - int ret; 143 - u8 buf[2]; 144 - 145 - buf[0] = TSL2563_CMD | reg; 146 - buf[1] = value; 147 - 148 - ret = i2c_master_send(client, buf, sizeof(buf)); 149 - return (ret == sizeof(buf)) ? 0 : ret; 150 - } 151 - 152 - static int tsl2563_read(struct i2c_client *client, u8 reg, void *buf, int len) 153 - { 154 - int ret; 155 - u8 cmd = TSL2563_CMD | reg; 156 - 157 - ret = i2c_master_send(client, &cmd, sizeof(cmd)); 158 - if (ret != sizeof(cmd)) 159 - return ret; 160 - 161 - return i2c_master_recv(client, buf, len); 162 - } 163 - 164 140 static int tsl2563_set_power(struct tsl2563_chip *chip, int on) 165 141 { 166 142 struct i2c_client *client = chip->client; 167 143 u8 cmd; 168 144 169 145 cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF; 170 - return tsl2563_write(client, TSL2563_REG_CTRL, cmd); 146 + return i2c_smbus_write_byte_data(client, 147 + TSL2563_CMD | TSL2563_REG_CTRL, cmd); 171 148 } 172 149 173 150 /* ··· 155 178 { 156 179 struct i2c_client *client = chip->client; 157 180 int ret; 158 - u8 val; 159 181 160 - ret = tsl2563_read(client, TSL2563_REG_CTRL, &val, sizeof(val)); 161 - if (ret != sizeof(val)) 182 + ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_CTRL); 183 + if (ret < 0) 162 184 return ret; 163 185 164 - return (val & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON; 186 + return (ret & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON; 165 187 } 166 188 167 189 static int tsl2563_configure(struct tsl2563_chip *chip) 168 190 { 169 191 int ret; 170 192 171 - ret = tsl2563_write(chip->client, TSL2563_REG_TIMING, 193 + ret = i2c_smbus_write_byte_data(chip->client, 194 + TSL2563_CMD | TSL2563_REG_TIMING, 172 195 chip->gainlevel->gaintime); 173 196 if (ret) 174 197 goto error_ret; 175 - ret = tsl2563_write(chip->client, TSL2563_REG_HIGHLOW, 198 + ret = i2c_smbus_write_byte_data(chip->client, 199 + TSL2563_CMD | TSL2563_REG_HIGHLOW, 176 200 chip->high_thres & 0xFF); 177 201 if (ret) 178 202 goto error_ret; 179 - ret = tsl2563_write(chip->client, TSL2563_REG_HIGHHIGH, 203 + ret = i2c_smbus_write_byte_data(chip->client, 204 + TSL2563_CMD | TSL2563_REG_HIGHHIGH, 180 205 (chip->high_thres >> 8) & 0xFF); 181 206 if (ret) 182 207 goto error_ret; 183 - ret = tsl2563_write(chip->client, TSL2563_REG_LOWLOW, 208 + ret = i2c_smbus_write_byte_data(chip->client, 209 + TSL2563_CMD | TSL2563_REG_LOWLOW, 184 210 chip->low_thres & 0xFF); 185 211 if (ret) 186 212 goto error_ret; 187 - ret = tsl2563_write(chip->client, TSL2563_REG_LOWHIGH, 213 + ret = i2c_smbus_write_byte_data(chip->client, 214 + TSL2563_CMD | TSL2563_REG_LOWHIGH, 188 215 (chip->low_thres >> 8) & 0xFF); 189 216 /* Interrupt register is automatically written anyway if it is relevant 190 217 so is not here */ ··· 223 242 struct i2c_client *client = chip->client; 224 243 int ret; 225 244 226 - ret = tsl2563_read(client, TSL2563_REG_ID, id, sizeof(*id)); 227 - if (ret != sizeof(*id)) 245 + ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_ID); 246 + if (ret < 0) 228 247 return ret; 229 248 230 249 return 0; ··· 294 313 (adc > chip->gainlevel->max) ? 295 314 chip->gainlevel++ : chip->gainlevel--; 296 315 297 - tsl2563_write(client, TSL2563_REG_TIMING, 298 - chip->gainlevel->gaintime); 316 + i2c_smbus_write_byte_data(client, 317 + TSL2563_CMD | TSL2563_REG_TIMING, 318 + chip->gainlevel->gaintime); 299 319 300 320 tsl2563_wait_adc(chip); 301 321 tsl2563_wait_adc(chip); ··· 309 327 static int tsl2563_get_adc(struct tsl2563_chip *chip) 310 328 { 311 329 struct i2c_client *client = chip->client; 312 - u8 buf0[2], buf1[2]; 313 330 u16 adc0, adc1; 314 331 int retry = 1; 315 332 int ret = 0; ··· 331 350 } 332 351 333 352 while (retry) { 334 - ret = tsl2563_read(client, 335 - TSL2563_REG_DATA0LOW, 336 - buf0, sizeof(buf0)); 337 - if (ret != sizeof(buf0)) 353 + ret = i2c_smbus_read_word_data(client, 354 + TSL2563_CMD | TSL2563_REG_DATA0LOW); 355 + if (ret < 0) 338 356 goto out; 357 + adc0 = ret; 339 358 340 - ret = tsl2563_read(client, TSL2563_REG_DATA1LOW, 341 - buf1, sizeof(buf1)); 342 - if (ret != sizeof(buf1)) 359 + ret = i2c_smbus_read_word_data(client, 360 + TSL2563_CMD | TSL2563_REG_DATA1LOW); 361 + if (ret < 0) 343 362 goto out; 344 - 345 - adc0 = (buf0[1] << 8) + buf0[0]; 346 - adc1 = (buf1[1] << 8) + buf1[0]; 363 + adc1 = ret; 347 364 348 365 retry = tsl2563_adjust_gainlevel(chip, adc0); 349 366 } ··· 572 593 else 573 594 address = TSL2563_REG_LOWLOW; 574 595 mutex_lock(&chip->lock); 575 - ret = tsl2563_write(chip->client, address, val & 0xFF); 596 + ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | address, 597 + val & 0xFF); 576 598 if (ret) 577 599 goto error_ret; 578 - ret = tsl2563_write(chip->client, address + 1, 579 - (val >> 8) & 0xFF); 600 + ret = i2c_smbus_write_byte_data(chip->client, 601 + TSL2563_CMD | (address + 1), 602 + (val >> 8) & 0xFF); 580 603 if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING) 581 604 chip->high_thres = val; 582 605 else ··· 594 613 { 595 614 struct iio_dev *dev_info = private; 596 615 struct tsl2563_chip *chip = iio_priv(dev_info); 597 - u8 cmd = TSL2563_CMD | TSL2563_CLEARINT; 598 616 599 617 iio_push_event(dev_info, 0, 600 618 IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_LIGHT, ··· 603 623 iio_get_time_ns()); 604 624 605 625 /* clear the interrupt and push the event */ 606 - i2c_master_send(chip->client, &cmd, sizeof(cmd)); 626 + i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT); 607 627 return IRQ_HANDLED; 608 628 } 609 629 ··· 628 648 if (ret) 629 649 goto out; 630 650 } 631 - ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); 651 + ret = i2c_smbus_write_byte_data(chip->client, 652 + TSL2563_CMD | TSL2563_REG_INT, 653 + chip->intr); 632 654 chip->int_enabled = true; 633 655 } 634 656 635 657 if (!state && (chip->intr & 0x30)) { 636 658 chip->intr |= ~0x30; 637 - ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); 659 + ret = i2c_smbus_write_byte_data(chip->client, 660 + TSL2563_CMD | TSL2563_REG_INT, 661 + chip->intr); 638 662 chip->int_enabled = false; 639 663 /* now the interrupt is not enabled, we can go to sleep */ 640 664 schedule_delayed_work(&chip->poweroff_work, 5 * HZ); ··· 653 669 int event_code) 654 670 { 655 671 struct tsl2563_chip *chip = iio_priv(indio_dev); 656 - u8 rxbuf; 657 672 int ret; 658 673 659 674 mutex_lock(&chip->lock); 660 - ret = tsl2563_read(chip->client, TSL2563_REG_INT, 661 - &rxbuf, sizeof(rxbuf)); 675 + ret = i2c_smbus_read_byte_data(chip->client, 676 + TSL2563_CMD | TSL2563_REG_INT); 662 677 mutex_unlock(&chip->lock); 663 678 if (ret < 0) 664 679 goto error_ret; 665 - ret = !!(rxbuf & 0x30); 680 + ret = !!(ret & 0x30); 666 681 error_ret: 667 682 668 683 return ret; ··· 783 800 cancel_delayed_work(&chip->poweroff_work); 784 801 /* Ensure that interrupts are disabled - then flush any bottom halves */ 785 802 chip->intr |= ~0x30; 786 - tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); 803 + i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT, 804 + chip->intr); 787 805 flush_scheduled_work(); 788 806 tsl2563_set_power(chip, 0); 789 807 if (client->irq)