Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / drivers / media / dvb / frontends / s921_core.c
CommitLineData
aa56cb9d
MR
1/*
2 * Driver for Sharp s921 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 */
7
8
9#include <linux/kernel.h>
10#include <linux/module.h>
c2e591fc 11#include <linux/delay.h>
aa56cb9d
MR
12#include "s921_core.h"
13
14static int s921_isdb_init(struct s921_isdb_t *dev);
15static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
16static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
17static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
18
19static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
c2e591fc
MCC
20 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
21 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
22 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
23 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
24 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
25 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
26 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
27 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
28 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
29 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
30 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
31 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
32 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
33 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
34 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
35 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
36 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
37 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
38 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
39 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
40 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
41 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
42 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
43 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
44 0xf8, 0xd7 };
aa56cb9d
MR
45
46static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
c2e591fc
MCC
47 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
48 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
49 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
50 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
51 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
52 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
53 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
54 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
55 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
56 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
57 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
58 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
59 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
60 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
61 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
62 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
aa56cb9d
MR
63
64int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
65 switch(cmd) {
66 case ISDB_T_CMD_INIT:
67 s921_isdb_init(dev);
68 break;
69 case ISDB_T_CMD_SET_PARAM:
70 s921_isdb_set_parameters(dev, data);
71 break;
72 case ISDB_T_CMD_TUNE:
73 s921_isdb_tune(dev, data);
74 break;
75 case ISDB_T_CMD_GET_STATUS:
76 s921_isdb_get_status(dev, data);
77 break;
78 default:
79 printk("unhandled command\n");
80 return -EINVAL;
81 }
82 return 0;
83}
84
85static int s921_isdb_init(struct s921_isdb_t *dev) {
86 unsigned int i;
87 unsigned int ret;
c2e591fc 88 printk("isdb_init\n");
aa56cb9d
MR
89 for (i = 0; i < sizeof(init_table); i+=2) {
90 ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
91 if (ret != 0) {
92 printk("i2c write failed\n");
93 return ret;
94 }
95 }
96 return 0;
97}
98
99static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
100
101 int ret;
102 /* auto is sufficient for now, lateron this should be reflected in an extra interface */
103
104
105
106 ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
107 ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
108
109 if (ret < 0)
110 return -EINVAL;
111
112 ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
113 if (ret < 0)
114 return -EINVAL;
115
116 ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
117 if (ret < 0)
118 return -EINVAL;
119
120 ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
121 if (ret < 0)
122 return -EINVAL;
123
124 ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
125 if (ret < 0)
126 return -EINVAL;
127
128 ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
129 if (ret < 0)
130 return -EINVAL;
131
132 return E_OK;
133}
134
135static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
136
137 int ret;
138 int index;
139
140 index = (params->frequency - 473143000)/6000000;
141
142 if (index > 48) {
143 return -EINVAL;
144 }
145
146 dev->i2c_write(dev->priv_dev, 0x47, 0x60);
147
148 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
149 if (ret < 0)
150 return -EINVAL;
151
152 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
153 if (ret < 0)
154 return -EINVAL;
155
156 ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
157 if (ret < 0)
158 return -EINVAL;
159
160 ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
161 if (ret < 0)
162 return -EINVAL;
163
164 ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
165 if (ret < 0)
166 return -EINVAL;
167
168 ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
169 if (ret < 0)
170 return -EINVAL;
171
172 ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
173 if (ret < 0)
174 return -EINVAL;
175
176 ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
177 if (ret < 0)
178 return -EINVAL;
179
180 ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
181 if (ret < 0)
182 return -EINVAL;
183
184 ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
185 if (ret < 0)
186 return -EINVAL;
187
188 ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
189 if (ret < 0)
190 return -EINVAL;
191
192 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
193 if (ret < 0)
194 return -EINVAL;
195
196 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
197 if (ret < 0)
198 return -EINVAL;
199
200 dev->i2c_write(dev->priv_dev, 0x01, 0x40);
201 return 0;
202}
203
204static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
205 unsigned int *ret = (unsigned int*)data;
206 u8 ifagc_dt;
207 u8 rfagc_dt;
208
209 mdelay(10);
210 ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
211 rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
212 if (rfagc_dt == 0x40) {
213 *ret = 1;
214 }
215 return 0;
216}