~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/staging/cxd2099/cxd2099.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cxd2099.c: Driver for the CXD2099AR Common Interface Controller
 
3
 *
 
4
 * Copyright (C) 2010 DigitalDevices UG
 
5
 *
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License
 
9
 * version 2 only, as published by the Free Software Foundation.
 
10
 *
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
21
 * 02110-1301, USA
 
22
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 
23
 */
 
24
 
 
25
#include <linux/version.h>
 
26
#include <linux/slab.h>
 
27
#include <linux/kernel.h>
 
28
#include <linux/module.h>
 
29
#include <linux/moduleparam.h>
 
30
#include <linux/init.h>
 
31
#include <linux/i2c.h>
 
32
#include <linux/wait.h>
 
33
#include <linux/delay.h>
 
34
#include <linux/mutex.h>
 
35
#include <linux/io.h>
 
36
 
 
37
#include "cxd2099.h"
 
38
 
 
39
#define MAX_BUFFER_SIZE 248
 
40
 
 
41
struct cxd {
 
42
        struct dvb_ca_en50221 en;
 
43
 
 
44
        struct i2c_adapter *i2c;
 
45
        u8     adr;
 
46
        u8     regs[0x23];
 
47
        u8     lastaddress;
 
48
        u8     clk_reg_f;
 
49
        u8     clk_reg_b;
 
50
        int    mode;
 
51
        u32    bitrate;
 
52
        int    ready;
 
53
        int    dr;
 
54
        int    slot_stat;
 
55
 
 
56
        u8     amem[1024];
 
57
        int    amem_read;
 
58
 
 
59
        int    cammode;
 
60
        struct mutex lock;
 
61
};
 
62
 
 
63
static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
 
64
                         u8 reg, u8 data)
 
65
{
 
66
        u8 m[2] = {reg, data};
 
67
        struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};
 
68
 
 
69
        if (i2c_transfer(adapter, &msg, 1) != 1) {
 
70
                printk(KERN_ERR "Failed to write to I2C register %02x@%02x!\n",
 
71
                       reg, adr);
 
72
                return -1;
 
73
        }
 
74
        return 0;
 
75
}
 
76
 
 
77
static int i2c_write(struct i2c_adapter *adapter, u8 adr,
 
78
                     u8 *data, u8 len)
 
79
{
 
80
        struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};
 
81
 
 
82
        if (i2c_transfer(adapter, &msg, 1) != 1) {
 
83
                printk(KERN_ERR "Failed to write to I2C!\n");
 
84
                return -1;
 
85
        }
 
86
        return 0;
 
87
}
 
88
 
 
89
static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
 
90
                        u8 reg, u8 *val)
 
91
{
 
92
        struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
 
93
                                   .buf = &reg, .len = 1 },
 
94
                                  {.addr = adr, .flags = I2C_M_RD,
 
95
                                   .buf = val, .len = 1 } };
 
96
 
 
97
        if (i2c_transfer(adapter, msgs, 2) != 2) {
 
98
                printk(KERN_ERR "error in i2c_read_reg\n");
 
99
                return -1;
 
100
        }
 
101
        return 0;
 
102
}
 
103
 
 
104
static int i2c_read(struct i2c_adapter *adapter, u8 adr,
 
105
                    u8 reg, u8 *data, u8 n)
 
106
{
 
107
        struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
 
108
                                   .buf = &reg, .len = 1 },
 
109
                                  {.addr = adr, .flags = I2C_M_RD,
 
110
                                   .buf = data, .len = n } };
 
111
 
 
112
        if (i2c_transfer(adapter, msgs, 2) != 2) {
 
113
                printk(KERN_ERR "error in i2c_read\n");
 
114
                return -1;
 
115
        }
 
116
        return 0;
 
117
}
 
118
 
 
119
static int read_block(struct cxd *ci, u8 adr, u8 *data, u8 n)
 
120
{
 
121
        int status;
 
122
 
 
123
        status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
 
124
        if (!status) {
 
125
                ci->lastaddress = adr;
 
126
                status = i2c_read(ci->i2c, ci->adr, 1, data, n);
 
127
        }
 
128
        return status;
 
129
}
 
130
 
 
131
static int read_reg(struct cxd *ci, u8 reg, u8 *val)
 
132
{
 
133
        return read_block(ci, reg, val, 1);
 
134
}
 
135
 
 
136
 
 
137
static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
 
138
{
 
139
        int status;
 
140
        u8 addr[3] = { 2, address&0xff, address>>8 };
 
141
 
 
142
        status = i2c_write(ci->i2c, ci->adr, addr, 3);
 
143
        if (!status)
 
144
                status = i2c_read(ci->i2c, ci->adr, 3, data, n);
 
145
        return status;
 
146
}
 
147
 
 
148
static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
 
149
{
 
150
        int status;
 
151
        u8 addr[3] = { 2, address&0xff, address>>8 };
 
152
 
 
153
        status = i2c_write(ci->i2c, ci->adr, addr, 3);
 
154
        if (!status) {
 
155
                u8 buf[256] = {3};
 
156
                memcpy(buf+1, data, n);
 
157
                status = i2c_write(ci->i2c, ci->adr, buf, n+1);
 
158
        }
 
159
        return status;
 
160
}
 
161
 
 
162
static int read_io(struct cxd *ci, u16 address, u8 *val)
 
163
{
 
164
        int status;
 
165
        u8 addr[3] = { 2, address&0xff, address>>8 };
 
166
 
 
167
        status = i2c_write(ci->i2c, ci->adr, addr, 3);
 
168
        if (!status)
 
169
                status = i2c_read(ci->i2c, ci->adr, 3, val, 1);
 
170
        return status;
 
171
}
 
172
 
 
173
static int write_io(struct cxd *ci, u16 address, u8 val)
 
174
{
 
175
        int status;
 
176
        u8 addr[3] = { 2, address&0xff, address>>8 };
 
177
        u8 buf[2] = { 3, val };
 
178
 
 
179
        status = i2c_write(ci->i2c, ci->adr, addr, 3);
 
180
        if (!status)
 
181
                status = i2c_write(ci->i2c, ci->adr, buf, 2);
 
182
 
 
183
        return status;
 
184
}
 
185
 
 
186
 
 
187
static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
 
188
{
 
189
        int status;
 
190
 
 
191
        status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
 
192
        if (!status && reg >= 6 && reg <= 8 && mask != 0xff)
 
193
                status = i2c_read_reg(ci->i2c, ci->adr, 1, &ci->regs[reg]);
 
194
        ci->regs[reg] = (ci->regs[reg]&(~mask))|val;
 
195
        if (!status) {
 
196
                ci->lastaddress = reg;
 
197
                status = i2c_write_reg(ci->i2c, ci->adr, 1, ci->regs[reg]);
 
198
        }
 
199
        if (reg == 0x20)
 
200
                ci->regs[reg] &= 0x7f;
 
201
        return status;
 
202
}
 
203
 
 
204
static int write_reg(struct cxd *ci, u8 reg, u8 val)
 
205
{
 
206
        return write_regm(ci, reg, val, 0xff);
 
207
}
 
208
 
 
209
#ifdef BUFFER_MODE
 
210
static int write_block(struct cxd *ci, u8 adr, u8 *data, int n)
 
211
{
 
212
        int status;
 
213
        u8 buf[256] = {1};
 
214
 
 
215
        status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
 
216
        if (!status) {
 
217
                ci->lastaddress = adr;
 
218
                memcpy(buf+1, data, n);
 
219
                status = i2c_write(ci->i2c, ci->adr, buf, n+1);
 
220
        }
 
221
        return status;
 
222
}
 
223
#endif
 
224
 
 
225
static void set_mode(struct cxd *ci, int mode)
 
226
{
 
227
        if (mode == ci->mode)
 
228
                return;
 
229
 
 
230
        switch (mode) {
 
231
        case 0x00: /* IO mem */
 
232
                write_regm(ci, 0x06, 0x00, 0x07);
 
233
                break;
 
234
        case 0x01: /* ATT mem */
 
235
                write_regm(ci, 0x06, 0x02, 0x07);
 
236
                break;
 
237
        default:
 
238
                break;
 
239
        }
 
240
        ci->mode = mode;
 
241
}
 
242
 
 
243
static void cam_mode(struct cxd *ci, int mode)
 
244
{
 
245
        if (mode == ci->cammode)
 
246
                return;
 
247
 
 
248
        switch (mode) {
 
249
        case 0x00:
 
250
                write_regm(ci, 0x20, 0x80, 0x80);
 
251
                break;
 
252
        case 0x01:
 
253
                printk(KERN_INFO "enable cam buffer mode\n");
 
254
                /* write_reg(ci, 0x0d, 0x00); */
 
255
                /* write_reg(ci, 0x0e, 0x01); */
 
256
                write_regm(ci, 0x08, 0x40, 0x40);
 
257
                /* read_reg(ci, 0x12, &dummy); */
 
258
                write_regm(ci, 0x08, 0x80, 0x80);
 
259
                break;
 
260
        default:
 
261
                break;
 
262
        }
 
263
        ci->cammode = mode;
 
264
}
 
265
 
 
266
 
 
267
 
 
268
#define CHK_ERROR(s) if ((status = s)) break
 
269
 
 
270
static int init(struct cxd *ci)
 
271
{
 
272
        int status;
 
273
 
 
274
        mutex_lock(&ci->lock);
 
275
        ci->mode = -1;
 
276
        do {
 
277
                CHK_ERROR(write_reg(ci, 0x00, 0x00));
 
278
                CHK_ERROR(write_reg(ci, 0x01, 0x00));
 
279
                CHK_ERROR(write_reg(ci, 0x02, 0x10));
 
280
                CHK_ERROR(write_reg(ci, 0x03, 0x00));
 
281
                CHK_ERROR(write_reg(ci, 0x05, 0xFF));
 
282
                CHK_ERROR(write_reg(ci, 0x06, 0x1F));
 
283
                CHK_ERROR(write_reg(ci, 0x07, 0x1F));
 
284
                CHK_ERROR(write_reg(ci, 0x08, 0x28));
 
285
                CHK_ERROR(write_reg(ci, 0x14, 0x20));
 
286
 
 
287
                CHK_ERROR(write_reg(ci, 0x09, 0x4D)); /* Input Mode C, BYPass Serial, TIVAL = low, MSB */
 
288
                CHK_ERROR(write_reg(ci, 0x0A, 0xA7)); /* TOSTRT = 8, Mode B (gated clock), falling Edge, Serial, POL=HIGH, MSB */
 
289
 
 
290
                /* Sync detector */
 
291
                CHK_ERROR(write_reg(ci, 0x0B, 0x33));
 
292
                CHK_ERROR(write_reg(ci, 0x0C, 0x33));
 
293
 
 
294
                CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F));
 
295
                CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b));
 
296
                CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F));
 
297
                CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f));
 
298
 
 
299
                CHK_ERROR(write_reg(ci, 0x20, 0x28)); /* Integer Divider, Falling Edge, Internal Sync, */
 
300
                CHK_ERROR(write_reg(ci, 0x21, 0x00)); /* MCLKI = TICLK/8 */
 
301
                CHK_ERROR(write_reg(ci, 0x22, 0x07)); /* MCLKI = TICLK/8 */
 
302
 
 
303
 
 
304
                CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80)); /* Reset CAM state machine */
 
305
 
 
306
                CHK_ERROR(write_regm(ci, 0x03, 0x02, 02));  /* Enable IREQA Interrupt */
 
307
                CHK_ERROR(write_reg(ci, 0x01, 0x04));  /* Enable CD Interrupt */
 
308
                CHK_ERROR(write_reg(ci, 0x00, 0x31));  /* Enable TS1,Hot Swap,Slot A */
 
309
                CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08));  /* Put TS in bypass */
 
310
                ci->cammode = -1;
 
311
#ifdef BUFFER_MODE
 
312
                cam_mode(ci, 0);
 
313
#endif
 
314
        } while (0);
 
315
        mutex_unlock(&ci->lock);
 
316
 
 
317
        return 0;
 
318
}
 
319
 
 
320
 
 
321
static int read_attribute_mem(struct dvb_ca_en50221 *ca,
 
322
                              int slot, int address)
 
323
{
 
324
        struct cxd *ci = ca->data;
 
325
        u8 val;
 
326
        mutex_lock(&ci->lock);
 
327
        set_mode(ci, 1);
 
328
        read_pccard(ci, address, &val, 1);
 
329
        mutex_unlock(&ci->lock);
 
330
        return val;
 
331
}
 
332
 
 
333
 
 
334
static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
 
335
                               int address, u8 value)
 
336
{
 
337
        struct cxd *ci = ca->data;
 
338
 
 
339
        mutex_lock(&ci->lock);
 
340
        set_mode(ci, 1);
 
341
        write_pccard(ci, address, &value, 1);
 
342
        mutex_unlock(&ci->lock);
 
343
        return 0;
 
344
}
 
345
 
 
346
static int read_cam_control(struct dvb_ca_en50221 *ca,
 
347
                            int slot, u8 address)
 
348
{
 
349
        struct cxd *ci = ca->data;
 
350
        u8 val;
 
351
 
 
352
        mutex_lock(&ci->lock);
 
353
        set_mode(ci, 0);
 
354
        read_io(ci, address, &val);
 
355
        mutex_unlock(&ci->lock);
 
356
        return val;
 
357
}
 
358
 
 
359
static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
 
360
                             u8 address, u8 value)
 
361
{
 
362
        struct cxd *ci = ca->data;
 
363
 
 
364
        mutex_lock(&ci->lock);
 
365
        set_mode(ci, 0);
 
366
        write_io(ci, address, value);
 
367
        mutex_unlock(&ci->lock);
 
368
        return 0;
 
369
}
 
370
 
 
371
static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
 
372
{
 
373
        struct cxd *ci = ca->data;
 
374
 
 
375
        mutex_lock(&ci->lock);
 
376
        cam_mode(ci, 0);
 
377
        write_reg(ci, 0x00, 0x21);
 
378
        write_reg(ci, 0x06, 0x1F);
 
379
        write_reg(ci, 0x00, 0x31);
 
380
        write_regm(ci, 0x20, 0x80, 0x80);
 
381
        write_reg(ci, 0x03, 0x02);
 
382
        ci->ready = 0;
 
383
        ci->mode = -1;
 
384
        {
 
385
                int i;
 
386
                for (i = 0; i < 100; i++) {
 
387
                        msleep(10);
 
388
                        if (ci->ready)
 
389
                                break;
 
390
                }
 
391
        }
 
392
        mutex_unlock(&ci->lock);
 
393
        /* msleep(500); */
 
394
        return 0;
 
395
}
 
396
 
 
397
static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 
398
{
 
399
        struct cxd *ci = ca->data;
 
400
 
 
401
        printk(KERN_INFO "slot_shutdown\n");
 
402
        mutex_lock(&ci->lock);
 
403
        /* write_regm(ci, 0x09, 0x08, 0x08); */
 
404
        write_regm(ci, 0x20, 0x80, 0x80);
 
405
        write_regm(ci, 0x06, 0x07, 0x07);
 
406
        ci->mode = -1;
 
407
        mutex_unlock(&ci->lock);
 
408
        return 0; /* shutdown(ci); */
 
409
}
 
410
 
 
411
static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
 
412
{
 
413
        struct cxd *ci = ca->data;
 
414
 
 
415
        mutex_lock(&ci->lock);
 
416
        write_regm(ci, 0x09, 0x00, 0x08);
 
417
        set_mode(ci, 0);
 
418
#ifdef BUFFER_MODE
 
419
        cam_mode(ci, 1);
 
420
#endif
 
421
        mutex_unlock(&ci->lock);
 
422
        return 0;
 
423
}
 
424
 
 
425
 
 
426
static int campoll(struct cxd *ci)
 
427
{
 
428
        u8 istat;
 
429
 
 
430
        read_reg(ci, 0x04, &istat);
 
431
        if (!istat)
 
432
                return 0;
 
433
        write_reg(ci, 0x05, istat);
 
434
 
 
435
        if (istat&0x40) {
 
436
                ci->dr = 1;
 
437
                printk(KERN_INFO "DR\n");
 
438
        }
 
439
        if (istat&0x20)
 
440
                printk(KERN_INFO "WC\n");
 
441
 
 
442
        if (istat&2) {
 
443
                u8 slotstat;
 
444
 
 
445
                read_reg(ci, 0x01, &slotstat);
 
446
                if (!(2&slotstat)) {
 
447
                        if (!ci->slot_stat) {
 
448
                                ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
 
449
                                write_regm(ci, 0x03, 0x08, 0x08);
 
450
                        }
 
451
 
 
452
                } else {
 
453
                        if (ci->slot_stat) {
 
454
                                ci->slot_stat = 0;
 
455
                                write_regm(ci, 0x03, 0x00, 0x08);
 
456
                                printk(KERN_INFO "NO CAM\n");
 
457
                                ci->ready = 0;
 
458
                        }
 
459
                }
 
460
                if (istat&8 && ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
 
461
                        ci->ready = 1;
 
462
                        ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
 
463
                        printk(KERN_INFO "READY\n");
 
464
                }
 
465
        }
 
466
        return 0;
 
467
}
 
468
 
 
469
 
 
470
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
 
471
{
 
472
        struct cxd *ci = ca->data;
 
473
        u8 slotstat;
 
474
 
 
475
        mutex_lock(&ci->lock);
 
476
        campoll(ci);
 
477
        read_reg(ci, 0x01, &slotstat);
 
478
        mutex_unlock(&ci->lock);
 
479
 
 
480
        return ci->slot_stat;
 
481
}
 
482
 
 
483
#ifdef BUFFER_MODE
 
484
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
 
485
{
 
486
        struct cxd *ci = ca->data;
 
487
        u8 msb, lsb;
 
488
        u16 len;
 
489
 
 
490
        mutex_lock(&ci->lock);
 
491
        campoll(ci);
 
492
        mutex_unlock(&ci->lock);
 
493
 
 
494
        printk(KERN_INFO "read_data\n");
 
495
        if (!ci->dr)
 
496
                return 0;
 
497
 
 
498
        mutex_lock(&ci->lock);
 
499
        read_reg(ci, 0x0f, &msb);
 
500
        read_reg(ci, 0x10, &lsb);
 
501
        len = (msb<<8)|lsb;
 
502
        read_block(ci, 0x12, ebuf, len);
 
503
        ci->dr = 0;
 
504
        mutex_unlock(&ci->lock);
 
505
 
 
506
        return len;
 
507
}
 
508
 
 
509
static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
 
510
{
 
511
        struct cxd *ci = ca->data;
 
512
 
 
513
        mutex_lock(&ci->lock);
 
514
        printk(KERN_INFO "write_data %d\n", ecount);
 
515
        write_reg(ci, 0x0d, ecount>>8);
 
516
        write_reg(ci, 0x0e, ecount&0xff);
 
517
        write_block(ci, 0x11, ebuf, ecount);
 
518
        mutex_unlock(&ci->lock);
 
519
        return ecount;
 
520
}
 
521
#endif
 
522
 
 
523
static struct dvb_ca_en50221 en_templ = {
 
524
        .read_attribute_mem  = read_attribute_mem,
 
525
        .write_attribute_mem = write_attribute_mem,
 
526
        .read_cam_control    = read_cam_control,
 
527
        .write_cam_control   = write_cam_control,
 
528
        .slot_reset          = slot_reset,
 
529
        .slot_shutdown       = slot_shutdown,
 
530
        .slot_ts_enable      = slot_ts_enable,
 
531
        .poll_slot_status    = poll_slot_status,
 
532
#ifdef BUFFER_MODE
 
533
        .read_data           = read_data,
 
534
        .write_data          = write_data,
 
535
#endif
 
536
 
 
537
};
 
538
 
 
539
struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv,
 
540
                                      struct i2c_adapter *i2c)
 
541
{
 
542
        struct cxd *ci = 0;
 
543
        u32 bitrate = 62000000;
 
544
        u8 val;
 
545
 
 
546
        if (i2c_read_reg(i2c, adr, 0, &val) < 0) {
 
547
                printk(KERN_ERR "No CXD2099 detected at %02x\n", adr);
 
548
                return 0;
 
549
        }
 
550
 
 
551
        ci = kmalloc(sizeof(struct cxd), GFP_KERNEL);
 
552
        if (!ci)
 
553
                return 0;
 
554
        memset(ci, 0, sizeof(*ci));
 
555
 
 
556
        mutex_init(&ci->lock);
 
557
        ci->i2c = i2c;
 
558
        ci->adr = adr;
 
559
        ci->lastaddress = 0xff;
 
560
        ci->clk_reg_b = 0x4a;
 
561
        ci->clk_reg_f = 0x1b;
 
562
        ci->bitrate = bitrate;
 
563
 
 
564
        memcpy(&ci->en, &en_templ, sizeof(en_templ));
 
565
        ci->en.data = ci;
 
566
        init(ci);
 
567
        printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->adr);
 
568
        return &ci->en;
 
569
}
 
570
EXPORT_SYMBOL(cxd2099_attach);
 
571
 
 
572
MODULE_DESCRIPTION("cxd2099");
 
573
MODULE_AUTHOR("Ralph Metzler <rjkm@metzlerbros.de>");
 
574
MODULE_LICENSE("GPL");