1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// SPDX-License-Identifier: GPL-2.0
/*
* AD5338R, AD5671R, AD5673R, AD5675R, AD5677R, AD5691R, AD5692R, AD5693,
* AD5693R, AD5694, AD5694R, AD5695R, AD5696, AD5696R
* Digital to analog converters driver
*
* Copyright 2018 Analog Devices Inc.
*/
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <asm/byteorder.h>
#include "ad5686.h"
static int ad5686_i2c_read(struct ad5686_state *st, u8 addr)
{
struct i2c_client *i2c = to_i2c_client(st->dev);
struct i2c_msg msg[2] = {
{
.addr = i2c->addr,
.flags = i2c->flags,
.len = 3,
.buf = &st->data[0].d8[1],
},
{
.addr = i2c->addr,
.flags = i2c->flags | I2C_M_RD,
.len = 2,
.buf = (char *)&st->data[0].d16,
},
};
int ret;
st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP) |
AD5686_ADDR(addr) |
0x00);
ret = i2c_transfer(i2c->adapter, msg, 2);
if (ret < 0)
return ret;
return be16_to_cpu(st->data[0].d16);
}
static int ad5686_i2c_write(struct ad5686_state *st,
u8 cmd, u8 addr, u16 val)
{
struct i2c_client *i2c = to_i2c_client(st->dev);
int ret;
st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | AD5686_ADDR(addr)
| val);
ret = i2c_master_send(i2c, &st->data[0].d8[1], 3);
if (ret < 0)
return ret;
return (ret != 3) ? -EIO : 0;
}
static const struct ad5686_bus_ops ad5686_i2c_ops = {
.write = ad5686_i2c_write,
.read = ad5686_i2c_read,
};
static int ad5686_i2c_probe(struct i2c_client *i2c)
{
return ad5686_probe(&i2c->dev, i2c_get_match_data(i2c),
i2c->name, &ad5686_i2c_ops);
}
static const struct i2c_device_id ad5686_i2c_id[] = {
{ .name = "ad5311r", .driver_data = (kernel_ulong_t)&ad5311r_chip_info },
{ .name = "ad5337r", .driver_data = (kernel_ulong_t)&ad5337r_chip_info },
{ .name = "ad5338r", .driver_data = (kernel_ulong_t)&ad5338r_chip_info },
{ .name = "ad5671r", .driver_data = (kernel_ulong_t)&ad5672r_chip_info },
{ .name = "ad5673r", .driver_data = (kernel_ulong_t)&ad5674r_chip_info },
{ .name = "ad5675r", .driver_data = (kernel_ulong_t)&ad5676r_chip_info },
{ .name = "ad5677r", .driver_data = (kernel_ulong_t)&ad5679r_chip_info },
{ .name = "ad5691r", .driver_data = (kernel_ulong_t)&ad5681r_chip_info },
{ .name = "ad5692r", .driver_data = (kernel_ulong_t)&ad5682r_chip_info },
{ .name = "ad5693", .driver_data = (kernel_ulong_t)&ad5683_chip_info },
{ .name = "ad5693r", .driver_data = (kernel_ulong_t)&ad5683r_chip_info },
{ .name = "ad5694", .driver_data = (kernel_ulong_t)&ad5684_chip_info },
{ .name = "ad5694r", .driver_data = (kernel_ulong_t)&ad5684r_chip_info },
{ .name = "ad5695r", .driver_data = (kernel_ulong_t)&ad5685r_chip_info },
{ .name = "ad5696", .driver_data = (kernel_ulong_t)&ad5686_chip_info },
{ .name = "ad5696r", .driver_data = (kernel_ulong_t)&ad5686r_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5686_i2c_id);
static const struct of_device_id ad5686_of_match[] = {
{ .compatible = "adi,ad5311r", .data = &ad5311r_chip_info },
{ .compatible = "adi,ad5337r", .data = &ad5337r_chip_info },
{ .compatible = "adi,ad5338r", .data = &ad5338r_chip_info },
{ .compatible = "adi,ad5671r", .data = &ad5672r_chip_info },
{ .compatible = "adi,ad5675r", .data = &ad5676r_chip_info },
{ .compatible = "adi,ad5691r", .data = &ad5681r_chip_info },
{ .compatible = "adi,ad5692r", .data = &ad5682r_chip_info },
{ .compatible = "adi,ad5693", .data = &ad5683_chip_info },
{ .compatible = "adi,ad5693r", .data = &ad5683r_chip_info },
{ .compatible = "adi,ad5694", .data = &ad5684_chip_info },
{ .compatible = "adi,ad5694r", .data = &ad5684r_chip_info },
{ .compatible = "adi,ad5695r", .data = &ad5685r_chip_info },
{ .compatible = "adi,ad5696", .data = &ad5686_chip_info },
{ .compatible = "adi,ad5696r", .data = &ad5686r_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad5686_of_match);
static struct i2c_driver ad5686_i2c_driver = {
.driver = {
.name = "ad5696",
.of_match_table = ad5686_of_match,
},
.probe = ad5686_i2c_probe,
.id_table = ad5686_i2c_id,
};
module_i2c_driver(ad5686_i2c_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS("IIO_AD5686");
|