diff options
Diffstat (limited to 'drivers/media/dvb/frontends/s921_module.c')
-rw-r--r-- | drivers/media/dvb/frontends/s921_module.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c new file mode 100644 index 000000000000..3cbb9cb2cf47 --- /dev/null +++ b/drivers/media/dvb/frontends/s921_module.c | |||
@@ -0,0 +1,190 @@ | |||
1 | /* | ||
2 | * Driver for Sharp s921 driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> | ||
5 | * | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include "dvb_frontend.h" | ||
14 | #include "s921_module.h" | ||
15 | #include "s921_core.h" | ||
16 | |||
17 | static unsigned int debug = 0; | ||
18 | module_param(debug, int, 0644); | ||
19 | MODULE_PARM_DESC(debug,"s921 debugging (default off)"); | ||
20 | |||
21 | #define dprintk(fmt, args...) if (debug) do {\ | ||
22 | printk("s921 debug: " fmt, ##args); } while (0) | ||
23 | |||
24 | struct s921_state | ||
25 | { | ||
26 | struct dvb_frontend frontend; | ||
27 | fe_modulation_t current_modulation; | ||
28 | __u32 snr; | ||
29 | __u32 current_frequency; | ||
30 | __u8 addr; | ||
31 | struct s921_isdb_t dev; | ||
32 | struct i2c_adapter *i2c; | ||
33 | }; | ||
34 | |||
35 | static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { | ||
36 | struct s921_state *state = (struct s921_state *)fe->demodulator_priv; | ||
37 | struct s921_isdb_t_transmission_mode_params params; | ||
38 | struct s921_isdb_t_tune_params tune_params; | ||
39 | |||
40 | tune_params.frequency = param->frequency; | ||
41 | s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); | ||
42 | s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); | ||
43 | mdelay(100); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int s921_init(struct dvb_frontend *fe) { | ||
48 | printk("s921 init\n"); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int s921_sleep(struct dvb_frontend *fe) { | ||
53 | printk("s921 sleep\n"); | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
58 | { | ||
59 | struct s921_state *state = (struct s921_state *)fe->demodulator_priv; | ||
60 | unsigned int ret; | ||
61 | mdelay(5); | ||
62 | s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); | ||
63 | *status = 0; | ||
64 | |||
65 | printk("status: %02x\n", ret); | ||
66 | if (ret == 1) { | ||
67 | *status |= FE_HAS_CARRIER; | ||
68 | *status |= FE_HAS_VITERBI; | ||
69 | *status |= FE_HAS_LOCK; | ||
70 | *status |= FE_HAS_SYNC; | ||
71 | *status |= FE_HAS_SIGNAL; | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) | ||
78 | { | ||
79 | dprintk("read ber\n"); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) | ||
84 | { | ||
85 | dprintk("read snr\n"); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) | ||
90 | { | ||
91 | dprintk("read ucblocks\n"); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static void s921_release(struct dvb_frontend *fe) | ||
96 | { | ||
97 | struct s921_state *state = (struct s921_state *)fe->demodulator_priv; | ||
98 | kfree(state); | ||
99 | } | ||
100 | |||
101 | static struct dvb_frontend_ops demod_s921={ | ||
102 | .info = { | ||
103 | .name = "SHARP S921", | ||
104 | .type = FE_OFDM, | ||
105 | .frequency_min = 473143000, | ||
106 | .frequency_max = 767143000, | ||
107 | .frequency_stepsize = 6000000, | ||
108 | .frequency_tolerance = 0, | ||
109 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | | ||
110 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | | ||
111 | FE_CAN_FEC_AUTO | | ||
112 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | ||
113 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | | ||
114 | FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | | ||
115 | FE_CAN_MUTE_TS | ||
116 | }, | ||
117 | .init = s921_init, | ||
118 | .sleep = s921_sleep, | ||
119 | .set_frontend = s921_set_parameters, | ||
120 | .read_snr = s921_read_snr, | ||
121 | .read_ber = s921_read_ber, | ||
122 | .read_status = s921_read_status, | ||
123 | .read_ucblocks = s921_read_ucblocks, | ||
124 | .release = s921_release, | ||
125 | }; | ||
126 | |||
127 | static int s921_write(void *dev, u8 reg, u8 val) { | ||
128 | struct s921_state *state = dev; | ||
129 | char buf[2]={reg,val}; | ||
130 | int err; | ||
131 | struct i2c_msg i2cmsgs = { | ||
132 | .addr = state->addr, | ||
133 | .flags = 0, | ||
134 | .len = 2, | ||
135 | .buf = buf | ||
136 | }; | ||
137 | |||
138 | if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { | ||
139 | printk("%s i2c_transfer error %d\n", __FUNCTION__, err); | ||
140 | if (err < 0) | ||
141 | return err; | ||
142 | else | ||
143 | return -EREMOTEIO; | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int s921_read(void *dev, u8 reg) { | ||
150 | struct s921_state *state = dev; | ||
151 | u8 b1; | ||
152 | int ret; | ||
153 | struct i2c_msg msg[2] = { { .addr = state->addr, | ||
154 | .flags = 0, | ||
155 | .buf = ®, .len = 1 }, | ||
156 | { .addr = state->addr, | ||
157 | .flags = I2C_M_RD, | ||
158 | .buf = &b1, .len = 1 } }; | ||
159 | |||
160 | ret = i2c_transfer(state->i2c, msg, 2); | ||
161 | if (ret != 2) | ||
162 | return ret; | ||
163 | return b1; | ||
164 | } | ||
165 | |||
166 | struct dvb_frontend* s921_attach(const struct s921_config *config, | ||
167 | struct i2c_adapter *i2c) | ||
168 | { | ||
169 | |||
170 | struct s921_state *state; | ||
171 | state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); | ||
172 | memset(state, 0x0, sizeof(struct s921_state)); | ||
173 | |||
174 | state->addr = config->i2c_address; | ||
175 | state->i2c = i2c; | ||
176 | state->dev.i2c_write = &s921_write; | ||
177 | state->dev.i2c_read = &s921_read; | ||
178 | state->dev.priv_dev = state; | ||
179 | |||
180 | s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); | ||
181 | |||
182 | memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); | ||
183 | state->frontend.demodulator_priv = state; | ||
184 | return &state->frontend; | ||
185 | } | ||
186 | |||
187 | EXPORT_SYMBOL_GPL(s921_attach); | ||
188 | MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); | ||
189 | MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); | ||
190 | MODULE_LICENSE("GPL"); | ||