aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dibx000_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/dibx000_common.c')
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c279
1 files changed, 266 insertions, 13 deletions
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 2311c0a3406c..f6938f97feb4 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -17,9 +17,145 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
17 struct i2c_msg msg = { 17 struct i2c_msg msg = {
18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
19 }; 19 };
20
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 21 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21} 22}
22 23
24static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
25{
26 u8 wb[2] = { reg >> 8, reg & 0xff };
27 u8 rb[2];
28 struct i2c_msg msg[2] = {
29 {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
30 {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
31 };
32
33 if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
34 dprintk("i2c read error on %d", reg);
35
36 return (rb[0] << 8) | rb[1];
37}
38
39static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
40{
41 int i = 100;
42 u16 status;
43
44 while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
45 ;
46
47 /* i2c timed out */
48 if (i == 0)
49 return -EREMOTEIO;
50
51 /* no acknowledge */
52 if ((status & 0x0080) == 0)
53 return -EREMOTEIO;
54
55 return 0;
56}
57
58static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
59{
60 u16 data;
61 u16 da;
62 u16 i;
63 u16 txlen = msg->len, len;
64 const u8 *b = msg->buf;
65
66 while (txlen) {
67 dibx000_read_word(mst, mst->base_reg + 2);
68
69 len = txlen > 8 ? 8 : txlen;
70 for (i = 0; i < len; i += 2) {
71 data = *b++ << 8;
72 if (i+1 < len)
73 data |= *b++;
74 dibx000_write_word(mst, mst->base_reg, data);
75 }
76 da = (((u8) (msg->addr)) << 9) |
77 (1 << 8) |
78 (1 << 7) |
79 (0 << 6) |
80 (0 << 5) |
81 ((len & 0x7) << 2) |
82 (0 << 1) |
83 (0 << 0);
84
85 if (txlen == msg->len)
86 da |= 1 << 5; /* start */
87
88 if (txlen-len == 0 && stop)
89 da |= 1 << 6; /* stop */
90
91 dibx000_write_word(mst, mst->base_reg+1, da);
92
93 if (dibx000_is_i2c_done(mst) != 0)
94 return -EREMOTEIO;
95 txlen -= len;
96 }
97
98 return 0;
99}
100
101static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
102{
103 u16 da;
104 u8 *b = msg->buf;
105 u16 rxlen = msg->len, len;
106
107 while (rxlen) {
108 len = rxlen > 8 ? 8 : rxlen;
109 da = (((u8) (msg->addr)) << 9) |
110 (1 << 8) |
111 (1 << 7) |
112 (0 << 6) |
113 (0 << 5) |
114 ((len & 0x7) << 2) |
115 (1 << 1) |
116 (0 << 0);
117
118 if (rxlen == msg->len)
119 da |= 1 << 5; /* start */
120
121 if (rxlen-len == 0)
122 da |= 1 << 6; /* stop */
123 dibx000_write_word(mst, mst->base_reg+1, da);
124
125 if (dibx000_is_i2c_done(mst) != 0)
126 return -EREMOTEIO;
127
128 rxlen -= len;
129
130 while (len) {
131 da = dibx000_read_word(mst, mst->base_reg);
132 *b++ = (da >> 8) & 0xff;
133 len--;
134 if (len >= 1) {
135 *b++ = da & 0xff;
136 len--;
137 }
138 }
139 }
140
141 return 0;
142}
143
144int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
145{
146 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
147
148 if (mst->device_rev < DIB7000MC && speed < 235)
149 speed = 235;
150 return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
151
152}
153EXPORT_SYMBOL(dibx000_i2c_set_speed);
154
155static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
156{
157 return I2C_FUNC_I2C;
158}
23 159
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, 160static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
25 enum dibx000_i2c_interface intf) 161 enum dibx000_i2c_interface intf)
@@ -32,6 +168,60 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
32 return 0; 168 return 0;
33} 169}
34 170
171static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
172{
173 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
174 int msg_index;
175 int ret = 0;
176
177 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
178 for (msg_index = 0; msg_index < num; msg_index++) {
179 if (msg[msg_index].flags & I2C_M_RD) {
180 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
181 if (ret != 0)
182 return 0;
183 } else {
184 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
185 if (ret != 0)
186 return 0;
187 }
188 }
189
190 return num;
191}
192
193static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
194{
195 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
196 int msg_index;
197 int ret = 0;
198
199 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
200 for (msg_index = 0; msg_index < num; msg_index++) {
201 if (msg[msg_index].flags & I2C_M_RD) {
202 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
203 if (ret != 0)
204 return 0;
205 } else {
206 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
207 if (ret != 0)
208 return 0;
209 }
210 }
211
212 return num;
213}
214
215static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
216 .master_xfer = dibx000_i2c_master_xfer_gpio12,
217 .functionality = dibx000_i2c_func,
218};
219
220static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
221 .master_xfer = dibx000_i2c_master_xfer_gpio34,
222 .functionality = dibx000_i2c_func,
223};
224
35static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], 225static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
36 u8 addr, int onoff) 226 u8 addr, int onoff)
37{ 227{
@@ -54,11 +244,37 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
54 return 0; 244 return 0;
55} 245}
56 246
57static u32 dibx000_i2c_func(struct i2c_adapter *adapter) 247static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
248 struct i2c_msg msg[], int num)
58{ 249{
59 return I2C_FUNC_I2C; 250 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
251 struct i2c_msg m[2 + num];
252 u8 tx_open[4], tx_close[4];
253
254 memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
255
256 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
257
258 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
259 m[0].addr = mst->i2c_addr;
260 m[0].buf = tx_open;
261 m[0].len = 4;
262
263 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
264
265 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
266 m[num + 1].addr = mst->i2c_addr;
267 m[num + 1].buf = tx_close;
268 m[num + 1].len = 4;
269
270 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
60} 271}
61 272
273static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
274 .master_xfer = dibx000_i2c_gated_gpio67_xfer,
275 .functionality = dibx000_i2c_func,
276};
277
62static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, 278static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
63 struct i2c_msg msg[], int num) 279 struct i2c_msg msg[], int num)
64{ 280{
@@ -91,8 +307,8 @@ static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
91}; 307};
92 308
93struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, 309struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
94 enum dibx000_i2c_interface intf, 310 enum dibx000_i2c_interface intf,
95 int gating) 311 int gating)
96{ 312{
97 struct i2c_adapter *i2c = NULL; 313 struct i2c_adapter *i2c = NULL;
98 314
@@ -101,6 +317,18 @@ struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
101 if (gating) 317 if (gating)
102 i2c = &mst->gated_tuner_i2c_adap; 318 i2c = &mst->gated_tuner_i2c_adap;
103 break; 319 break;
320 case DIBX000_I2C_INTERFACE_GPIO_1_2:
321 if (!gating)
322 i2c = &mst->master_i2c_adap_gpio12;
323 break;
324 case DIBX000_I2C_INTERFACE_GPIO_3_4:
325 if (!gating)
326 i2c = &mst->master_i2c_adap_gpio34;
327 break;
328 case DIBX000_I2C_INTERFACE_GPIO_6_7:
329 if (gating)
330 i2c = &mst->master_i2c_adap_gpio67;
331 break;
104 default: 332 default:
105 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); 333 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
106 break; 334 break;
@@ -126,8 +354,8 @@ void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
126EXPORT_SYMBOL(dibx000_reset_i2c_master); 354EXPORT_SYMBOL(dibx000_reset_i2c_master);
127 355
128static int i2c_adapter_init(struct i2c_adapter *i2c_adap, 356static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
129 struct i2c_algorithm *algo, const char *name, 357 struct i2c_algorithm *algo, const char *name,
130 struct dibx000_i2c_master *mst) 358 struct dibx000_i2c_master *mst)
131{ 359{
132 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); 360 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
133 i2c_adap->algo = algo; 361 i2c_adap->algo = algo;
@@ -139,7 +367,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
139} 367}
140 368
141int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, 369int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
142 struct i2c_adapter *i2c_adap, u8 i2c_addr) 370 struct i2c_adapter *i2c_adap, u8 i2c_addr)
143{ 371{
144 u8 tx[4]; 372 u8 tx[4];
145 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 }; 373 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
@@ -153,11 +381,33 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
153 else 381 else
154 mst->base_reg = 768; 382 mst->base_reg = 768;
155 383
384 mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
385 if (i2c_adapter_init
386 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
387 "DiBX000 tuner I2C bus", mst) != 0)
388 printk(KERN_ERR
389 "DiBX000: could not initialize the tuner i2c_adapter\n");
390
391 mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
392 if (i2c_adapter_init
393 (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
394 "DiBX000 master GPIO12 I2C bus", mst) != 0)
395 printk(KERN_ERR
396 "DiBX000: could not initialize the master i2c_adapter\n");
397
398 mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
399 if (i2c_adapter_init
400 (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
401 "DiBX000 master GPIO34 I2C bus", mst) != 0)
402 printk(KERN_ERR
403 "DiBX000: could not initialize the master i2c_adapter\n");
404
405 mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
156 if (i2c_adapter_init 406 if (i2c_adapter_init
157 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, 407 (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
158 "DiBX000 tuner I2C bus", mst) != 0) 408 "DiBX000 master GPIO67 I2C bus", mst) != 0)
159 printk(KERN_ERR 409 printk(KERN_ERR
160 "DiBX000: could not initialize the tuner i2c_adapter\n"); 410 "DiBX000: could not initialize the master i2c_adapter\n");
161 411
162 /* initialize the i2c-master by closing the gate */ 412 /* initialize the i2c-master by closing the gate */
163 dibx000_i2c_gate_ctrl(mst, tx, 0, 0); 413 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
@@ -170,16 +420,19 @@ EXPORT_SYMBOL(dibx000_init_i2c_master);
170void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) 420void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
171{ 421{
172 i2c_del_adapter(&mst->gated_tuner_i2c_adap); 422 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
423 i2c_del_adapter(&mst->master_i2c_adap_gpio12);
424 i2c_del_adapter(&mst->master_i2c_adap_gpio34);
425 i2c_del_adapter(&mst->master_i2c_adap_gpio67);
173} 426}
174EXPORT_SYMBOL(dibx000_exit_i2c_master); 427EXPORT_SYMBOL(dibx000_exit_i2c_master);
175 428
176 429
177u32 systime(void) 430u32 systime(void)
178{ 431{
179 struct timespec t; 432 struct timespec t;
180 433
181 t = current_kernel_time(); 434 t = current_kernel_time();
182 return (t.tv_sec * 10000) + (t.tv_nsec / 100000); 435 return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
183} 436}
184EXPORT_SYMBOL(systime); 437EXPORT_SYMBOL(systime);
185 438