0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/module.h>
0011 #include <linux/string.h>
0012 #include <linux/slab.h>
0013 #include <linux/delay.h>
0014 #include <media/dvb_frontend.h>
0015 #include "s5h1432.h"
0016
0017 struct s5h1432_state {
0018
0019 struct i2c_adapter *i2c;
0020
0021
0022 const struct s5h1432_config *config;
0023
0024 struct dvb_frontend frontend;
0025
0026 enum fe_modulation current_modulation;
0027 unsigned int first_tune:1;
0028
0029 u32 current_frequency;
0030 int if_freq;
0031
0032 u8 inversion;
0033 };
0034
0035 static int debug;
0036
0037 #define dprintk(arg...) do { \
0038 if (debug) \
0039 printk(arg); \
0040 } while (0)
0041
0042 static int s5h1432_writereg(struct s5h1432_state *state,
0043 u8 addr, u8 reg, u8 data)
0044 {
0045 int ret;
0046 u8 buf[] = { reg, data };
0047
0048 struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 };
0049
0050 ret = i2c_transfer(state->i2c, &msg, 1);
0051
0052 if (ret != 1)
0053 printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, ret == %i)\n",
0054 __func__, addr, reg, data, ret);
0055
0056 return (ret != 1) ? -1 : 0;
0057 }
0058
0059 static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg)
0060 {
0061 int ret;
0062 u8 b0[] = { reg };
0063 u8 b1[] = { 0 };
0064
0065 struct i2c_msg msg[] = {
0066 {.addr = addr, .flags = 0, .buf = b0, .len = 1},
0067 {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1}
0068 };
0069
0070 ret = i2c_transfer(state->i2c, msg, 2);
0071
0072 if (ret != 2)
0073 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
0074 __func__, ret);
0075 return b1[0];
0076 }
0077
0078 static int s5h1432_sleep(struct dvb_frontend *fe)
0079 {
0080 return 0;
0081 }
0082
0083 static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe,
0084 u32 bandwidth)
0085 {
0086 struct s5h1432_state *state = fe->demodulator_priv;
0087
0088 u8 reg = 0;
0089
0090
0091 reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E);
0092 reg &= ~(0x0C);
0093 switch (bandwidth) {
0094 case 6:
0095 reg |= 0x08;
0096 break;
0097 case 7:
0098 reg |= 0x04;
0099 break;
0100 case 8:
0101 reg |= 0x00;
0102 break;
0103 default:
0104 return 0;
0105 }
0106 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg);
0107 return 1;
0108 }
0109
0110 static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz)
0111 {
0112 struct s5h1432_state *state = fe->demodulator_priv;
0113
0114 switch (ifFreqHz) {
0115 case TAIWAN_HI_IF_FREQ_44_MHZ:
0116 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
0117 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
0118 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15);
0119 break;
0120 case EUROPE_HI_IF_FREQ_36_MHZ:
0121 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
0122 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
0123 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40);
0124 break;
0125 case IF_FREQ_6_MHZ:
0126 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
0127 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
0128 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0);
0129 break;
0130 case IF_FREQ_3point3_MHZ:
0131 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
0132 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
0133 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
0134 break;
0135 case IF_FREQ_3point5_MHZ:
0136 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
0137 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
0138 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED);
0139 break;
0140 case IF_FREQ_4_MHZ:
0141 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA);
0142 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA);
0143 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA);
0144 break;
0145 default:
0146 {
0147 u32 value = 0;
0148 value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 *
0149 (u32) 32768) / (48 * 1000));
0150 printk(KERN_INFO
0151 "Default IFFreq %d :reg value = 0x%x\n",
0152 ifFreqHz, value);
0153 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4,
0154 (u8) value & 0xFF);
0155 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5,
0156 (u8) (value >> 8) & 0xFF);
0157 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7,
0158 (u8) (value >> 16) & 0xFF);
0159 break;
0160 }
0161
0162 }
0163
0164 return 1;
0165 }
0166
0167
0168 static int s5h1432_set_frontend(struct dvb_frontend *fe)
0169 {
0170 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0171 u32 dvb_bandwidth = 8;
0172 struct s5h1432_state *state = fe->demodulator_priv;
0173
0174 if (p->frequency == state->current_frequency) {
0175
0176
0177 } else {
0178 fe->ops.tuner_ops.set_params(fe);
0179 msleep(300);
0180 s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
0181 switch (p->bandwidth_hz) {
0182 case 6000000:
0183 dvb_bandwidth = 6;
0184 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0185 break;
0186 case 7000000:
0187 dvb_bandwidth = 7;
0188 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0189 break;
0190 case 8000000:
0191 dvb_bandwidth = 8;
0192 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0193 break;
0194 default:
0195 return 0;
0196 }
0197
0198
0199 msleep(30);
0200 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
0201 msleep(30);
0202 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
0203
0204 s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
0205 switch (p->bandwidth_hz) {
0206 case 6000000:
0207 dvb_bandwidth = 6;
0208 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0209 break;
0210 case 7000000:
0211 dvb_bandwidth = 7;
0212 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0213 break;
0214 case 8000000:
0215 dvb_bandwidth = 8;
0216 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
0217 break;
0218 default:
0219 return 0;
0220 }
0221
0222
0223 msleep(30);
0224 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
0225 msleep(30);
0226 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
0227
0228 }
0229
0230 state->current_frequency = p->frequency;
0231
0232 return 0;
0233 }
0234
0235 static int s5h1432_init(struct dvb_frontend *fe)
0236 {
0237 struct s5h1432_state *state = fe->demodulator_priv;
0238
0239 u8 reg = 0;
0240 state->current_frequency = 0;
0241 printk(KERN_INFO " s5h1432_init().\n");
0242
0243
0244
0245
0246 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8);
0247 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01);
0248 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70);
0249 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80);
0250 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D);
0251 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30);
0252 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20);
0253 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B);
0254 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40);
0255 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84);
0256 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a);
0257 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3);
0258 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50);
0259 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c);
0260 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10);
0261 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c);
0262 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00);
0263 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94);
0264
0265 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00);
0266
0267
0268
0269
0270 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
0271 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
0272 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
0273
0274 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31);
0275
0276
0277 reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42);
0278 reg |= 0x80;
0279 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg);
0280
0281
0282
0283
0284 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
0285 msleep(30);
0286 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
0287
0288
0289 return 0;
0290 }
0291
0292 static int s5h1432_read_status(struct dvb_frontend *fe, enum fe_status *status)
0293 {
0294 return 0;
0295 }
0296
0297 static int s5h1432_read_signal_strength(struct dvb_frontend *fe,
0298 u16 *signal_strength)
0299 {
0300 return 0;
0301 }
0302
0303 static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr)
0304 {
0305 return 0;
0306 }
0307
0308 static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
0309 {
0310
0311 return 0;
0312 }
0313
0314 static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber)
0315 {
0316 return 0;
0317 }
0318
0319 static int s5h1432_get_tune_settings(struct dvb_frontend *fe,
0320 struct dvb_frontend_tune_settings *tune)
0321 {
0322 return 0;
0323 }
0324
0325 static void s5h1432_release(struct dvb_frontend *fe)
0326 {
0327 struct s5h1432_state *state = fe->demodulator_priv;
0328 kfree(state);
0329 }
0330
0331 static const struct dvb_frontend_ops s5h1432_ops;
0332
0333 struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
0334 struct i2c_adapter *i2c)
0335 {
0336 struct s5h1432_state *state = NULL;
0337
0338 printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
0339
0340 state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
0341 if (!state)
0342 return NULL;
0343
0344
0345 state->config = config;
0346 state->i2c = i2c;
0347 state->current_modulation = QAM_16;
0348 state->inversion = state->config->inversion;
0349
0350
0351 memcpy(&state->frontend.ops, &s5h1432_ops,
0352 sizeof(struct dvb_frontend_ops));
0353
0354 state->frontend.demodulator_priv = state;
0355
0356 return &state->frontend;
0357 }
0358 EXPORT_SYMBOL(s5h1432_attach);
0359
0360 static const struct dvb_frontend_ops s5h1432_ops = {
0361 .delsys = { SYS_DVBT },
0362 .info = {
0363 .name = "Samsung s5h1432 DVB-T Frontend",
0364 .frequency_min_hz = 177 * MHz,
0365 .frequency_max_hz = 858 * MHz,
0366 .frequency_stepsize_hz = 166666,
0367 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0368 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0369 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
0370 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
0371 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER},
0372
0373 .init = s5h1432_init,
0374 .sleep = s5h1432_sleep,
0375 .set_frontend = s5h1432_set_frontend,
0376 .get_tune_settings = s5h1432_get_tune_settings,
0377 .read_status = s5h1432_read_status,
0378 .read_ber = s5h1432_read_ber,
0379 .read_signal_strength = s5h1432_read_signal_strength,
0380 .read_snr = s5h1432_read_snr,
0381 .read_ucblocks = s5h1432_read_ucblocks,
0382 .release = s5h1432_release,
0383 };
0384
0385 module_param(debug, int, 0644);
0386 MODULE_PARM_DESC(debug, "Enable verbose debug messages");
0387
0388 MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver");
0389 MODULE_AUTHOR("Bill Liu");
0390 MODULE_LICENSE("GPL");