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#include "nv50.h"
26
27static int
28nvd0_i2c_sense_scl(struct nouveau_i2c_port *base)
29{
30 struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
31 struct nv50_i2c_port *port = (void *)base;
32 return !!(nv_rd32(priv, port->addr) & 0x00000010);
33}
34
35static int
36nvd0_i2c_sense_sda(struct nouveau_i2c_port *base)
37{
38 struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine;
39 struct nv50_i2c_port *port = (void *)base;
40 return !!(nv_rd32(priv, port->addr) & 0x00000020);
41}
42
43static const struct nouveau_i2c_func
44nvd0_i2c_func = {
45 .acquire = nv94_i2c_acquire,
46 .release = nv94_i2c_release,
47 .drive_scl = nv50_i2c_drive_scl,
48 .drive_sda = nv50_i2c_drive_sda,
49 .sense_scl = nvd0_i2c_sense_scl,
50 .sense_sda = nvd0_i2c_sense_sda,
51};
52
53static int
54nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
55 struct nouveau_oclass *oclass, void *data, u32 index,
56 struct nouveau_object **pobject)
57{
58 struct dcb_i2c_entry *info = data;
59 struct nv50_i2c_port *port;
60 int ret;
61
62 ret = nouveau_i2c_port_create(parent, engine, oclass, index,
63 &nouveau_i2c_bit_algo, &port);
64 *pobject = nv_object(port);
65 if (ret)
66 return ret;
67
68 port->base.func = &nvd0_i2c_func;
69 port->state = 0x00000007;
70 port->addr = 0x00d014 + (info->drive * 0x20);
71 if (info->share != DCB_I2C_UNUSED) {
72 port->ctrl = 0x00e500 + (info->share * 0x50);
73 port->data = 0x0000e001;
74 }
75 return 0;
76}
77
78static struct nouveau_oclass
79nvd0_i2c_sclass[] = {
80 { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
81 .ofuncs = &(struct nouveau_ofuncs) {
82 .ctor = nvd0_i2c_port_ctor,
83 .dtor = _nouveau_i2c_port_dtor,
84 .init = nv50_i2c_port_init,
85 .fini = _nouveau_i2c_port_fini,
86 },
87 },
88 { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX),
89 .ofuncs = &(struct nouveau_ofuncs) {
90 .ctor = nv94_aux_port_ctor,
91 .dtor = _nouveau_i2c_port_dtor,
92 .init = _nouveau_i2c_port_init,
93 .fini = _nouveau_i2c_port_fini,
94 },
95 },
96 {}
97};
98
99static int
100nvd0_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
101 struct nouveau_oclass *oclass, void *data, u32 size,
102 struct nouveau_object **pobject)
103{
104 struct nv50_i2c_priv *priv;
105 int ret;
106
107 ret = nouveau_i2c_create(parent, engine, oclass, nvd0_i2c_sclass, &priv);
108 *pobject = nv_object(priv);
109 if (ret)
110 return ret;
111
112 return 0;
113}
114
115struct nouveau_oclass
116nvd0_i2c_oclass = {
117 .handle = NV_SUBDEV(I2C, 0xd0),
118 .ofuncs = &(struct nouveau_ofuncs) {
119 .ctor = nvd0_i2c_ctor,
120 .dtor = _nouveau_i2c_dtor,
121 .init = _nouveau_i2c_init,
122 .fini = _nouveau_i2c_fini,
123 },
124};
125