Commit | Line | Data |
---|---|---|
35f6b6b8 SZ |
1 | /* |
2 | * I2C bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature | |
3 | * sensor, ADC and DAC | |
4 | * | |
5 | * Copyright 2010 Analog Devices Inc. | |
6 | * | |
7 | * Licensed under the GPL-2 or later. | |
8 | */ | |
9 | ||
10 | #include <linux/device.h> | |
11 | #include <linux/kernel.h> | |
12 | #include <linux/i2c.h> | |
13 | #include <linux/interrupt.h> | |
99c97852 | 14 | #include <linux/module.h> |
35f6b6b8 SZ |
15 | |
16 | #include "adt7316.h" | |
17 | ||
18 | /* | |
19 | * adt7316 register access by I2C | |
20 | */ | |
21 | static int adt7316_i2c_read(void *client, u8 reg, u8 *data) | |
22 | { | |
23 | struct i2c_client *cl = client; | |
8f27f732 | 24 | int ret; |
35f6b6b8 SZ |
25 | |
26 | ret = i2c_smbus_write_byte(cl, reg); | |
27 | if (ret < 0) { | |
28 | dev_err(&cl->dev, "I2C fail to select reg\n"); | |
29 | return ret; | |
30 | } | |
31 | ||
32 | ret = i2c_smbus_read_byte(client); | |
33 | if (ret < 0) { | |
34 | dev_err(&cl->dev, "I2C read error\n"); | |
35 | return ret; | |
36 | } | |
37 | ||
38 | return 0; | |
39 | } | |
40 | ||
41 | static int adt7316_i2c_write(void *client, u8 reg, u8 data) | |
42 | { | |
43 | struct i2c_client *cl = client; | |
44 | int ret = 0; | |
45 | ||
46 | ret = i2c_smbus_write_byte_data(cl, reg, data); | |
47 | if (ret < 0) | |
48 | dev_err(&cl->dev, "I2C write error\n"); | |
49 | ||
50 | return ret; | |
51 | } | |
52 | ||
53 | static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) | |
54 | { | |
55 | struct i2c_client *cl = client; | |
56 | int i, ret = 0; | |
57 | ||
58 | if (count > ADT7316_REG_MAX_ADDR) | |
59 | count = ADT7316_REG_MAX_ADDR; | |
60 | ||
61 | for (i = 0; i < count; i++) { | |
62 | ret = adt7316_i2c_read(cl, reg, &data[i]); | |
63 | if (ret < 0) { | |
64 | dev_err(&cl->dev, "I2C multi read error\n"); | |
65 | return ret; | |
66 | } | |
67 | } | |
68 | ||
69 | return 0; | |
70 | } | |
71 | ||
72 | static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) | |
73 | { | |
74 | struct i2c_client *cl = client; | |
75 | int i, ret = 0; | |
76 | ||
77 | if (count > ADT7316_REG_MAX_ADDR) | |
78 | count = ADT7316_REG_MAX_ADDR; | |
79 | ||
80 | for (i = 0; i < count; i++) { | |
81 | ret = adt7316_i2c_write(cl, reg, data[i]); | |
82 | if (ret < 0) { | |
83 | dev_err(&cl->dev, "I2C multi write error\n"); | |
84 | return ret; | |
85 | } | |
86 | } | |
87 | ||
88 | return 0; | |
89 | } | |
90 | ||
91 | /* | |
92 | * device probe and remove | |
93 | */ | |
94 | ||
4ae1c61f | 95 | static int adt7316_i2c_probe(struct i2c_client *client, |
35f6b6b8 SZ |
96 | const struct i2c_device_id *id) |
97 | { | |
98 | struct adt7316_bus bus = { | |
99 | .client = client, | |
100 | .irq = client->irq, | |
101 | .irq_flags = IRQF_TRIGGER_LOW, | |
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 | ||
35f6b6b8 SZ |
111 | static 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 | ||
121 | MODULE_DEVICE_TABLE(i2c, adt7316_i2c_id); | |
122 | ||
35f6b6b8 SZ |
123 | static struct i2c_driver adt7316_driver = { |
124 | .driver = { | |
125 | .name = "adt7316", | |
01788c53 | 126 | .pm = ADT7316_PM_OPS, |
35f6b6b8 SZ |
127 | }, |
128 | .probe = adt7316_i2c_probe, | |
35f6b6b8 SZ |
129 | .id_table = adt7316_i2c_id, |
130 | }; | |
6e5af184 | 131 | module_i2c_driver(adt7316_driver); |
35f6b6b8 SZ |
132 | |
133 | MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>"); | |
edf7abde | 134 | MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC"); |
35f6b6b8 | 135 | MODULE_LICENSE("GPL v2"); |