static struct lm92_data *lm92_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm92_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { dev_dbg(&client->dev, "Updating lm92 data\n"); data->temp1_input = i2c_smbus_read_word_swapped(client, LM92_REG_TEMP); data->temp1_hyst = i2c_smbus_read_word_swapped(client, LM92_REG_TEMP_HYST); data->temp1_crit = i2c_smbus_read_word_swapped(client, LM92_REG_TEMP_CRIT); data->temp1_min = i2c_smbus_read_word_swapped(client, LM92_REG_TEMP_LOW); data->temp1_max = i2c_smbus_read_word_swapped(client, LM92_REG_TEMP_HIGH); data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; }
/* Return 0 if detection is successful, -ENODEV otherwise */ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int i, config, cap, manid, devid; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); manid = i2c_smbus_read_word_swapped(client, JC42_REG_MANID); devid = i2c_smbus_read_word_swapped(client, JC42_REG_DEVICEID); if (cap < 0 || config < 0 || manid < 0 || devid < 0) return -ENODEV; if ((cap & 0xff00) || (config & 0xf800)) return -ENODEV; for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) { struct jc42_chips *chip = &jc42_chips[i]; if (manid == chip->manid && (devid & chip->devid_mask) == chip->devid) { strlcpy(info->type, "jc42", I2C_NAME_SIZE); return 0; } } return -ENODEV; }
static void ds620_init_client(struct i2c_client *client) { struct ds620_platform_data *ds620_info = client->dev.platform_data; u16 conf, new_conf; new_conf = conf = i2c_smbus_read_word_swapped(client, DS620_REG_CONF); new_conf &= ~DS620_REG_CONFIG_1SHOT; new_conf |= DS620_REG_CONFIG_PO2; if (ds620_info && ds620_info->pomode == 1) new_conf &= ~DS620_REG_CONFIG_PO1; else if (ds620_info && ds620_info->pomode == 2) new_conf |= DS620_REG_CONFIG_PO1; else new_conf &= ~DS620_REG_CONFIG_PO2; new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; if (conf != new_conf) i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf); i2c_smbus_write_byte(client, DS620_COM_START); }
/* * All registers are word-sized, except for the configuration register. * The LM77 uses the high-byte first convention. */ static u16 lm77_read_value(struct i2c_client *client, u8 reg) { if (reg == LM77_REG_CONF) return i2c_smbus_read_byte_data(client, reg); else return i2c_smbus_read_word_swapped(client, reg); }
/* * Registers 0x07 to 0x0c are word-sized, others are byte-sized * GL520 uses a high-byte first convention */ static int gl520_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) return i2c_smbus_read_word_swapped(client, reg); else return i2c_smbus_read_byte_data(client, reg); }
static struct ds620_data *ds620_update_client(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ds620_data *data = i2c_get_clientdata(client); struct ds620_data *ret = data; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { int i; int res; dev_dbg(&client->dev, "Starting ds620 update\n"); for (i = 0; i < ARRAY_SIZE(data->temp); i++) { res = i2c_smbus_read_word_swapped(client, DS620_REG_TEMP[i]); if (res < 0) { ret = ERR_PTR(res); goto abort; } data->temp[i] = res; } data->last_updated = jiffies; data->valid = 1; } abort: mutex_unlock(&data->update_lock); return ret; }
static inline int ad7414_read(struct i2c_client *client, u8 reg) { if (reg == AD7414_REG_TEMP) return i2c_smbus_read_word_swapped(client, reg); else return i2c_smbus_read_byte_data(client, reg); }
static ssize_t show_alarm(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ds620_data *data = ds620_update_client(dev); struct i2c_client *client = to_i2c_client(dev); u16 conf, new_conf; int res; if (IS_ERR(data)) return PTR_ERR(data); /* reset alarms if necessary */ res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF); if (res < 0) return res; new_conf = conf = res; new_conf &= ~attr->index; if (conf != new_conf) { res = i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf); if (res < 0) return res; } return sprintf(buf, "%d\n", !!(conf & attr->index)); }
static int si7005_read_measurement(struct si7005_data *data, bool temp) { int tries = 50; int ret; mutex_lock(&data->lock); ret = i2c_smbus_write_byte_data(data->client, SI7005_CONFIG, data->config | SI7005_CONFIG_START | (temp ? SI7005_CONFIG_TEMP : 0)); if (ret < 0) goto done; while (tries-- > 0) { msleep(20); ret = i2c_smbus_read_byte_data(data->client, SI7005_STATUS); if (ret < 0) goto done; if (!(ret & SI7005_STATUS_NRDY)) break; } if (tries < 0) { ret = -EIO; goto done; } ret = i2c_smbus_read_word_swapped(data->client, SI7005_DATA); done: mutex_unlock(&data->lock); return ret; }
/* Return the measurement value from the specified channel */ static int hmc5843_read_measurement(struct iio_dev *indio_dev, int address, int *val) { struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct hmc5843_data *data = iio_priv(indio_dev); s32 result; int tries = 150; mutex_lock(&data->lock); while (tries-- > 0) { result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG); if (result & HMC5843_DATA_READY) break; msleep(20); } if (tries < 0) { dev_err(&client->dev, "data not ready\n"); mutex_unlock(&data->lock); return -EIO; } result = i2c_smbus_read_word_swapped(client, address); mutex_unlock(&data->lock); if (result < 0) return -EINVAL; *val = result; return IIO_VAL_INT; }
static void ds620_init_client(struct i2c_client *client) { struct ds620_platform_data *ds620_info = client->dev.platform_data; u16 conf, new_conf; new_conf = conf = i2c_smbus_read_word_swapped(client, DS620_REG_CONF); /* switch to continuous conversion mode */ new_conf &= ~DS620_REG_CONFIG_1SHOT; /* already high at power-on, but don't trust the BIOS! */ new_conf |= DS620_REG_CONFIG_PO2; /* thermostat mode according to platform data */ if (ds620_info && ds620_info->pomode == 1) new_conf &= ~DS620_REG_CONFIG_PO1; /* PO_LOW */ else if (ds620_info && ds620_info->pomode == 2) new_conf |= DS620_REG_CONFIG_PO1; /* PO_HIGH */ else new_conf &= ~DS620_REG_CONFIG_PO2; /* always low */ /* with highest precision */ new_conf |= DS620_REG_CONFIG_R1 | DS620_REG_CONFIG_R0; if (conf != new_conf) i2c_smbus_write_word_swapped(client, DS620_REG_CONF, new_conf); /* start conversion */ i2c_smbus_write_byte(client, DS620_COM_START); }
static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct jc42_data *data; int config, cap, err; struct device *dev = &client->dev; data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL); if (!data) return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP); if (cap < 0) return cap; data->extended = !!(cap & JC42_CAP_RANGE); config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG); if (config < 0) return config; data->orig_config = config; if (config & JC42_CFG_SHUTDOWN) { config &= ~JC42_CFG_SHUTDOWN; i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config); } data->config = config; /* Register sysfs hooks */ err = sysfs_create_group(&dev->kobj, &jc42_group); if (err) return err; data->hwmon_dev = hwmon_device_register(dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove; } return 0; exit_remove: sysfs_remove_group(&dev->kobj, &jc42_group); return err; }
static struct jc42_data *jc42_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct jc42_data *data = i2c_get_clientdata(client); struct jc42_data *ret = data; int val; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP); if (val < 0) { ret = ERR_PTR(val); goto abort; } data->temp_input = val; val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_CRITICAL); if (val < 0) { ret = ERR_PTR(val); goto abort; } data->temp_crit = val; val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_LOWER); if (val < 0) { ret = ERR_PTR(val); goto abort; } data->temp_min = val; val = i2c_smbus_read_word_swapped(client, JC42_REG_TEMP_UPPER); if (val < 0) { ret = ERR_PTR(val); goto abort; } data->temp_max = val; data->last_updated = jiffies; data->valid = true; } abort: mutex_unlock(&data->update_lock); return ret; }
static int srf08_read_ranging(struct srf08_data *data) { struct i2c_client *client = data->client; int ret, i; int waittime; mutex_lock(&data->lock); ret = i2c_smbus_write_byte_data(data->client, SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM); if (ret < 0) { dev_err(&client->dev, "write command - err: %d\n", ret); mutex_unlock(&data->lock); return ret; } /* * we read here until a correct version number shows up as * suggested by the documentation * * with an ultrasonic speed of 343 m/s and a roundtrip of it * sleep the expected duration and try to read from the device * if nothing useful is read try it in a shorter grid * * polling for not more than 20 ms should be enough */ waittime = 1 + data->range_mm / 172; msleep(waittime); for (i = 0; i < 4; i++) { ret = i2c_smbus_read_byte_data(data->client, SRF08_READ_SW_REVISION); /* check if a valid version number is read */ if (ret < 255 && ret > 0) break; msleep(5); } if (ret >= 255 || ret <= 0) { dev_err(&client->dev, "device not ready\n"); mutex_unlock(&data->lock); return -EIO; } ret = i2c_smbus_read_word_swapped(data->client, SRF08_READ_ECHO_1_HIGH); if (ret < 0) { dev_err(&client->dev, "cannot read distance: ret=%d\n", ret); mutex_unlock(&data->lock); return ret; } mutex_unlock(&data->lock); return ret; }
static int max17040_read_reg(struct i2c_client *client, int reg) { int ret; ret = i2c_smbus_read_word_swapped(client, reg); if (ret < 0) dev_err(&client->dev, "%s: err %d\n", __func__, ret); return ret; }
static int tmp102_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); int config; config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (config < 0) return config; config &= ~TMP102_CONF_SD; return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config); }
static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); s32 val; val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); if (val < 0) return (int) val; *value = (u8) val; return 0; }
static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); s32 val; val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); if (val < 0) return (int) val; *value = (u16) val; return 0; }
static int si7020_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct i2c_client **client = iio_priv(indio_dev); int ret; switch (mask) { case IIO_CHAN_INFO_RAW: ret = i2c_smbus_read_word_swapped(*client, chan->type == IIO_TEMP ? SI7020CMD_TEMP_HOLD : SI7020CMD_RH_HOLD); if (ret < 0) return ret; *val = ret >> 2; /* * Humidity values can slightly exceed the 0-100%RH * range and should be corrected by software */ if (chan->type == IIO_HUMIDITYRELATIVE) *val = clamp_val(*val, 786, 13893); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: if (chan->type == IIO_TEMP) *val = 175720; /* = 175.72 * 1000 */ else *val = 125 * 1000; *val2 = 65536 >> 2; return IIO_VAL_FRACTIONAL; case IIO_CHAN_INFO_OFFSET: /* * Since iio_convert_raw_to_processed_unlocked assumes offset * is an integer we have to round these values and lose * accuracy. * Relative humidity will be 0.0032959% too high and * temperature will be 0.00277344 degrees too high. * This is no big deal because it's within the accuracy of the * sensor. */ if (chan->type == IIO_TEMP) *val = -4368; /* = -46.85 * (65536 >> 2) / 175.72 */ else *val = -786; /* = -6 * (65536 >> 2) / 125 */ return IIO_VAL_INT; default: break; } return -EINVAL; }
static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word) { int ret; struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); ret = i2c_smbus_read_word_swapped(st->client, MS5611_READ_PROM_WORD + (index << 1)); if (ret < 0) return ret; *word = ret; return 0; }
static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data) { struct i2c_client *client = chip->client; int ret = 0; ret = i2c_smbus_read_word_swapped(client, reg); if (ret < 0) { dev_err(&client->dev, "I2C read error\n"); return ret; } *data = ret; return 0; }
static ssize_t show_temp(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); int temp; s32 err = i2c_smbus_read_word_swapped(client, attr->index); if (err < 0) return err; /* use integer division instead of equivalent right shift to guarantee arithmetic shift and preserve the sign */ temp = (((s16) err) * 250) / 32; return scnprintf(buf, PAGE_SIZE, "%d\n", temp); }
static struct tmp102 *tmp102_update_device(struct i2c_client *client) { struct tmp102 *tmp102 = i2c_get_clientdata(client); mutex_lock(&tmp102->lock); if (time_after(jiffies, tmp102->last_update + HZ / 3)) { int i; for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { int status = i2c_smbus_read_word_swapped(client, tmp102_reg[i]); if (status > -1) tmp102->temp[i] = tmp102_reg_to_mC(status); } tmp102->last_update = jiffies; } mutex_unlock(&tmp102->lock); return tmp102; }
static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); s32 val; val = i2c_smbus_write_word_swapped(i2c, AD5593R_MODE_CONF | AD5592R_REG_ADC_SEQ, BIT(chan)); if (val < 0) return (int) val; val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); if (val < 0) return (int) val; *value = (u16) val; return 0; }
static int regmap_smbus_word_read_swapped(void *context, unsigned int reg, unsigned int *val) { struct device *dev = context; struct i2c_client *i2c = to_i2c_client(dev); int ret; if (reg > 0xff) return -EINVAL; ret = i2c_smbus_read_word_swapped(i2c, reg); if (ret < 0) return ret; *val = ret; return 0; }
static int tmp102_remove(struct i2c_client *client) { struct tmp102 *tmp102 = i2c_get_clientdata(client); thermal_zone_of_sensor_unregister(tmp102->hwmon_dev, tmp102->tz); hwmon_device_unregister(tmp102->hwmon_dev); /* Stop monitoring if device was stopped originally */ if (tmp102->config_orig & TMP102_CONF_SD) { int config; config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (config >= 0) i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config | TMP102_CONF_SD); } return 0; }
static int __devexit tmp102_remove(struct i2c_client *client) { struct tmp102 *tmp102 = i2c_get_clientdata(client); hwmon_device_unregister(tmp102->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); /* */ if (tmp102->config_orig & TMP102_CONF_SD) { int config; config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (config >= 0) i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config | TMP102_CONF_SD); } kfree(tmp102); return 0; }
static struct ds1621_data *ds1621_update_client(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ds1621_data *data = i2c_get_clientdata(client); u8 new_conf; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { int i; dev_dbg(&client->dev, "Starting ds1621 update\n"); data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF); for (i = 0; i < ARRAY_SIZE(data->temp); i++) data->temp[i] = i2c_smbus_read_word_swapped(client, DS1621_REG_TEMP[i]); /* */ new_conf = data->conf; if (data->temp[0] > data->temp[1]) /* */ new_conf &= ~DS1621_ALARM_TEMP_LOW; if (data->temp[0] < data->temp[2]) /* */ new_conf &= ~DS1621_ALARM_TEMP_HIGH; if (data->conf != new_conf) i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf); data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; }
static struct lm92_data *lm92_update_device(struct device *dev) { struct lm92_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; int i; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { dev_dbg(&client->dev, "Updating lm92 data\n"); for (i = 0; i < t_num_regs; i++) { data->temp[i] = i2c_smbus_read_word_swapped(client, regs[i]); } data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; }
static int tmp102_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tmp102 *tmp102; int status; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_err(&client->dev, "adapter doesn't support SMBus word transactions\n"); return -ENODEV; } tmp102 = devm_kzalloc(&client->dev, sizeof(*tmp102), GFP_KERNEL); if (!tmp102) return -ENOMEM; i2c_set_clientdata(client, tmp102); status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (status < 0) { dev_err(&client->dev, "error reading config register\n"); return status; } tmp102->config_orig = status; status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, TMP102_CONFIG); if (status < 0) { dev_err(&client->dev, "error writing config register\n"); goto fail_restore_config; } status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); if (status < 0) { dev_err(&client->dev, "error reading config register\n"); goto fail_restore_config; } status &= ~TMP102_CONFIG_RD_ONLY; if (status != TMP102_CONFIG) { dev_err(&client->dev, "config settings did not stick\n"); status = -ENODEV; goto fail_restore_config; } tmp102->last_update = jiffies - HZ; mutex_init(&tmp102->lock); status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); if (status) { dev_dbg(&client->dev, "could not create sysfs files\n"); goto fail_restore_config; } tmp102->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(tmp102->hwmon_dev)) { dev_dbg(&client->dev, "unable to register hwmon device\n"); status = PTR_ERR(tmp102->hwmon_dev); goto fail_remove_sysfs; } tmp102->tz = thermal_zone_of_sensor_register(&client->dev, 0, &client->dev, tmp102_read_temp, NULL); if (IS_ERR(tmp102->tz)) tmp102->tz = NULL; dev_info(&client->dev, "initialized\n"); return 0; fail_remove_sysfs: sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); fail_restore_config: i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, tmp102->config_orig); return status; }