Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * I2C bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature
  4 * sensor, ADC and DAC
  5 *
  6 * Copyright 2010 Analog Devices Inc.
  7 */
  8
  9#include <linux/device.h>
 10#include <linux/kernel.h>
 11#include <linux/i2c.h>
 12#include <linux/interrupt.h>
 13#include <linux/module.h>
 14
 15#include "adt7316.h"
 16
 17/*
 18 * adt7316 register access by I2C
 19 */
 20static int adt7316_i2c_read(void *client, u8 reg, u8 *data)
 21{
 22	struct i2c_client *cl = client;
 23	int ret;
 24
 25	ret = i2c_smbus_write_byte(cl, reg);
 26	if (ret < 0) {
 27		dev_err(&cl->dev, "I2C fail to select reg\n");
 28		return ret;
 29	}
 30
 31	ret = i2c_smbus_read_byte(client);
 32	if (ret < 0) {
 33		dev_err(&cl->dev, "I2C read error\n");
 34		return ret;
 35	}
 36
 37	*data = ret;
 38
 39	return 0;
 40}
 41
 42static int adt7316_i2c_write(void *client, u8 reg, u8 data)
 43{
 44	struct i2c_client *cl = client;
 45	int ret;
 46
 47	ret = i2c_smbus_write_byte_data(cl, reg, data);
 48	if (ret < 0)
 49		dev_err(&cl->dev, "I2C write error\n");
 50
 51	return ret;
 52}
 53
 54static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data)
 55{
 56	struct i2c_client *cl = client;
 57	int i, ret;
 58
 59	if (count > ADT7316_REG_MAX_ADDR)
 60		count = ADT7316_REG_MAX_ADDR;
 61
 62	for (i = 0; i < count; i++) {
 63		ret = adt7316_i2c_read(cl, reg, &data[i]);
 64		if (ret < 0) {
 65			dev_err(&cl->dev, "I2C multi read error\n");
 66			return ret;
 67		}
 68	}
 69
 70	return 0;
 71}
 72
 73static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data)
 74{
 75	struct i2c_client *cl = client;
 76	int i, ret;
 77
 78	if (count > ADT7316_REG_MAX_ADDR)
 79		count = ADT7316_REG_MAX_ADDR;
 80
 81	for (i = 0; i < count; i++) {
 82		ret = adt7316_i2c_write(cl, reg, data[i]);
 83		if (ret < 0) {
 84			dev_err(&cl->dev, "I2C multi write error\n");
 85			return ret;
 86		}
 87	}
 88
 89	return 0;
 90}
 91
 92/*
 93 * device probe and remove
 94 */
 95
 96static int adt7316_i2c_probe(struct i2c_client *client,
 97			     const struct i2c_device_id *id)
 98{
 99	struct adt7316_bus bus = {
100		.client = client,
101		.irq = client->irq,
102		.read = adt7316_i2c_read,
103		.write = adt7316_i2c_write,
104		.multi_read = adt7316_i2c_multi_read,
105		.multi_write = adt7316_i2c_multi_write,
106	};
107
108	return adt7316_probe(&client->dev, &bus, id->name);
109}
110
111static const struct i2c_device_id adt7316_i2c_id[] = {
112	{ "adt7316", 0 },
113	{ "adt7317", 0 },
114	{ "adt7318", 0 },
115	{ "adt7516", 0 },
116	{ "adt7517", 0 },
117	{ "adt7519", 0 },
118	{ }
119};
120
121MODULE_DEVICE_TABLE(i2c, adt7316_i2c_id);
122
123static const struct of_device_id adt7316_of_match[] = {
124	{ .compatible = "adi,adt7316" },
125	{ .compatible = "adi,adt7317" },
126	{ .compatible = "adi,adt7318" },
127	{ .compatible = "adi,adt7516" },
128	{ .compatible = "adi,adt7517" },
129	{ .compatible = "adi,adt7519" },
130	{ },
131};
132
133MODULE_DEVICE_TABLE(of, adt7316_of_match);
134
135static struct i2c_driver adt7316_driver = {
136	.driver = {
137		.name = "adt7316",
138		.of_match_table = adt7316_of_match,
139		.pm = ADT7316_PM_OPS,
140	},
141	.probe = adt7316_i2c_probe,
142	.id_table = adt7316_i2c_id,
143};
144module_i2c_driver(adt7316_driver);
145
146MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
147MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC");
148MODULE_LICENSE("GPL v2");