This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / dvb / frontends / dib3000-common.c
1 #include "dib3000-common.h"
2
3 #ifdef CONFIG_DVB_DIBCOM_DEBUG
4 static int debug;
5 module_param(debug, int, 0x644);
6 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
7 #endif
8 #define deb_info(args...) dprintk(0x01,args)
9 #define deb_i2c(args...) dprintk(0x02,args)
10 #define deb_srch(args...) dprintk(0x04,args)
11
12
13 int dib3000_read_reg(struct dib3000_state *state, u16 reg)
14 {
15         u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
16         u8 rb[2];
17         struct i2c_msg msg[] = {
18                 { .addr = state->config.demod_address, .flags = 0,        .buf = wb, .len = 2 },
19                 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
20         };
21
22         if (i2c_transfer(state->i2c, msg, 2) != 2)
23                 deb_i2c("i2c read error\n");
24
25         deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
26                         (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
27
28         return (rb[0] << 8) | rb[1];
29 }
30
31 int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
32 {
33         u8 b[] = {
34                 (reg >> 8) & 0xff, reg & 0xff,
35                 (val >> 8) & 0xff, val & 0xff,
36         };
37         struct i2c_msg msg[] = {
38                 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
39         };
40         deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
41
42         return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
43 }
44
45 int dib3000_init_pid_list(struct dib3000_state *state, int num)
46 {
47         int i;
48         if (state != NULL) {
49                 state->pid_list = kmalloc(sizeof(struct dib3000_pid) * num,GFP_KERNEL);
50                 if (state->pid_list == NULL)
51                         return -ENOMEM;
52
53                 deb_info("initializing %d pids for the pid_list.\n",num);
54                 state->pid_list_lock = SPIN_LOCK_UNLOCKED;
55                 memset(state->pid_list,0,num*(sizeof(struct dib3000_pid)));
56                 for (i=0; i < num; i++) {
57                         state->pid_list[i].pid = 0;
58                         state->pid_list[i].active = 0;
59                 }
60                 state->feedcount = 0;
61         } else
62                 return -EINVAL;
63
64         return 0;
65 }
66
67 void dib3000_dealloc_pid_list(struct dib3000_state *state)
68 {
69         if (state != NULL && state->pid_list != NULL)
70                 kfree(state->pid_list);
71 }
72
73 /* fetch a pid from pid_list */
74 int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids, int pid,
75                 spinlock_t *pid_list_lock,int onoff)
76 {
77         int i,ret = -1;
78         unsigned long flags;
79
80         spin_lock_irqsave(pid_list_lock,flags);
81         for (i=0; i < num_pids; i++)
82                 if (onoff) {
83                         if (!pid_list[i].active) {
84                                 pid_list[i].pid = pid;
85                                 pid_list[i].active = 1;
86                                 ret = i;
87                                 break;
88                         }
89                 } else {
90                         if (pid_list[i].active && pid_list[i].pid == pid) {
91                                 pid_list[i].pid = 0;
92                                 pid_list[i].active = 0;
93                                 ret = i;
94                                 break;
95                         }
96                 }
97
98         deb_info("setting pid: %5d %04x at index %d '%s'\n",pid,pid,ret,onoff ? "on" : "off");
99
100         spin_unlock_irqrestore(pid_list_lock,flags);
101         return ret;
102 }
103
104 int dib3000_search_status(u16 irq,u16 lock)
105 {
106         if (irq & 0x02) {
107                 if (lock & 0x01) {
108                         deb_srch("auto search succeeded\n");
109                         return 1; // auto search succeeded
110                 } else {
111                         deb_srch("auto search not successful\n");
112                         return 0; // auto search failed
113                 }
114         } else if (irq & 0x01)  {
115                 deb_srch("auto search failed\n");
116                 return 0; // auto search failed
117         }
118         return -1; // try again
119 }
120
121 /* for auto search */
122 u16 dib3000_seq[2][2][2] =     /* fft,gua,   inv   */
123         { /* fft */
124                 { /* gua */
125                         { 0, 1 },                   /*  0   0   { 0,1 } */
126                         { 3, 9 },                   /*  0   1   { 0,1 } */
127                 },
128                 {
129                         { 2, 5 },                   /*  1   0   { 0,1 } */
130                         { 6, 11 },                  /*  1   1   { 0,1 } */
131                 }
132         };
133
134 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
135 MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
136 MODULE_LICENSE("GPL");
137
138 EXPORT_SYMBOL(dib3000_seq);
139
140 EXPORT_SYMBOL(dib3000_read_reg);
141 EXPORT_SYMBOL(dib3000_write_reg);
142 EXPORT_SYMBOL(dib3000_init_pid_list);
143 EXPORT_SYMBOL(dib3000_dealloc_pid_list);
144 EXPORT_SYMBOL(dib3000_get_pid_index);
145 EXPORT_SYMBOL(dib3000_search_status);