/* * DS4424 DAC control register 8 bits * [7] 0: to sink; 1: to source * [6:0] steps to sink/source * bit[7] looks like a sign bit, but the value of the register is * not a two's complement code considering the bit[6:0] is a absolute * distance from the zero point.
*/ union ds4424_raw_data { struct {
u8 dx:7;
u8 source_bit:1;
};
u8 bits;
};
staticint ds4424_get_value(struct iio_dev *indio_dev, int *val, int channel)
{ struct ds4424_data *data = iio_priv(indio_dev); int ret;
mutex_lock(&data->lock);
ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel)); if (ret < 0) goto fail;
*val = ret;
fail:
mutex_unlock(&data->lock); return ret;
}
staticint ds4424_set_value(struct iio_dev *indio_dev, int val, struct iio_chan_spec const *chan)
{ struct ds4424_data *data = iio_priv(indio_dev); int ret;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(data->client,
DS4424_DAC_ADDR(chan->channel), val); if (ret < 0) goto fail;
data->raw[chan->channel] = val;
fail:
mutex_unlock(&data->lock); return ret;
}
staticint ds4424_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ union ds4424_raw_data raw; int ret;
switch (mask) { case IIO_CHAN_INFO_RAW:
ret = ds4424_get_value(indio_dev, val, chan->channel); if (ret < 0) {
pr_err("%s : ds4424_get_value returned %d\n",
__func__, ret); return ret;
}
raw.bits = *val;
*val = raw.dx; if (raw.source_bit == DS4424_SINK_I)
*val = -*val; return IIO_VAL_INT;
default: return -EINVAL;
}
}
staticint ds4424_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ union ds4424_raw_data raw;
if (val2 != 0) return -EINVAL;
switch (mask) { case IIO_CHAN_INFO_RAW: if (val < S8_MIN || val > S8_MAX) return -EINVAL;
staticint ds4424_verify_chip(struct iio_dev *indio_dev)
{ int ret, val;
ret = ds4424_get_value(indio_dev, &val, 0); if (ret < 0)
dev_err(&indio_dev->dev, "%s failed. ret: %d\n", __func__, ret);
return ret;
}
staticint ds4424_suspend(struct device *dev)
{ struct i2c_client *client = to_i2c_client(dev); struct iio_dev *indio_dev = i2c_get_clientdata(client); struct ds4424_data *data = iio_priv(indio_dev); int ret = 0; int i;
for (i = 0; i < indio_dev->num_channels; i++) {
data->save[i] = data->raw[i];
ret = ds4424_set_value(indio_dev, 0,
&indio_dev->channels[i]); if (ret < 0) return ret;
} return ret;
}
staticint ds4424_resume(struct device *dev)
{ struct i2c_client *client = to_i2c_client(dev); struct iio_dev *indio_dev = i2c_get_clientdata(client); struct ds4424_data *data = iio_priv(indio_dev); int ret = 0; int i;
for (i = 0; i < indio_dev->num_channels; i++) {
ret = ds4424_set_value(indio_dev, data->save[i],
&indio_dev->channels[i]); if (ret < 0) return ret;
} return ret;
}
data->vcc_reg = devm_regulator_get(&client->dev, "vcc"); if (IS_ERR(data->vcc_reg)) return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg), "Failed to get vcc-supply regulator.\n");
mutex_init(&data->lock);
ret = regulator_enable(data->vcc_reg); if (ret < 0) {
dev_err(&client->dev, "Unable to enable the regulator.\n"); return ret;
}
usleep_range(1000, 1200);
ret = ds4424_verify_chip(indio_dev); if (ret < 0) goto fail;
switch (id->driver_data) { case ID_DS4422:
indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS; break; case ID_DS4424:
indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS; break; default:
dev_err(&client->dev, "ds4424: Invalid chip id.\n");
ret = -ENXIO; goto fail;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.