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