1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 247b75ec1SPalash Bandyopadhyay /* 3955e6ed8SMauro Carvalho Chehab * Samsung s5h1432 DVB-T demodulator driver 4955e6ed8SMauro Carvalho Chehab * 5955e6ed8SMauro Carvalho Chehab * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.com> 647b75ec1SPalash Bandyopadhyay */ 747b75ec1SPalash Bandyopadhyay 847b75ec1SPalash Bandyopadhyay #include <linux/kernel.h> 947b75ec1SPalash Bandyopadhyay #include <linux/init.h> 1047b75ec1SPalash Bandyopadhyay #include <linux/module.h> 1147b75ec1SPalash Bandyopadhyay #include <linux/string.h> 1247b75ec1SPalash Bandyopadhyay #include <linux/slab.h> 1347b75ec1SPalash Bandyopadhyay #include <linux/delay.h> 14fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h> 1547b75ec1SPalash Bandyopadhyay #include "s5h1432.h" 1647b75ec1SPalash Bandyopadhyay 1747b75ec1SPalash Bandyopadhyay struct s5h1432_state { 1847b75ec1SPalash Bandyopadhyay 1947b75ec1SPalash Bandyopadhyay struct i2c_adapter *i2c; 2047b75ec1SPalash Bandyopadhyay 2147b75ec1SPalash Bandyopadhyay /* configuration settings */ 2247b75ec1SPalash Bandyopadhyay const struct s5h1432_config *config; 2347b75ec1SPalash Bandyopadhyay 2447b75ec1SPalash Bandyopadhyay struct dvb_frontend frontend; 2547b75ec1SPalash Bandyopadhyay 260df289a2SMauro Carvalho Chehab enum fe_modulation current_modulation; 2747b75ec1SPalash Bandyopadhyay unsigned int first_tune:1; 2847b75ec1SPalash Bandyopadhyay 2947b75ec1SPalash Bandyopadhyay u32 current_frequency; 3047b75ec1SPalash Bandyopadhyay int if_freq; 3147b75ec1SPalash Bandyopadhyay 3247b75ec1SPalash Bandyopadhyay u8 inversion; 3347b75ec1SPalash Bandyopadhyay }; 3447b75ec1SPalash Bandyopadhyay 3547b75ec1SPalash Bandyopadhyay static int debug; 3647b75ec1SPalash Bandyopadhyay 3747b75ec1SPalash Bandyopadhyay #define dprintk(arg...) do { \ 3847b75ec1SPalash Bandyopadhyay if (debug) \ 3947b75ec1SPalash Bandyopadhyay printk(arg); \ 4047b75ec1SPalash Bandyopadhyay } while (0) 4147b75ec1SPalash Bandyopadhyay 4247b75ec1SPalash Bandyopadhyay static int s5h1432_writereg(struct s5h1432_state *state, 4347b75ec1SPalash Bandyopadhyay u8 addr, u8 reg, u8 data) 4447b75ec1SPalash Bandyopadhyay { 4547b75ec1SPalash Bandyopadhyay int ret; 4647b75ec1SPalash Bandyopadhyay u8 buf[] = { reg, data }; 4747b75ec1SPalash Bandyopadhyay 4847b75ec1SPalash Bandyopadhyay struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 }; 4947b75ec1SPalash Bandyopadhyay 5047b75ec1SPalash Bandyopadhyay ret = i2c_transfer(state->i2c, &msg, 1); 5147b75ec1SPalash Bandyopadhyay 5247b75ec1SPalash Bandyopadhyay if (ret != 1) 534bd69e7bSMauro Carvalho Chehab printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, ret == %i)\n", 544bd69e7bSMauro Carvalho Chehab __func__, addr, reg, data, ret); 5547b75ec1SPalash Bandyopadhyay 5647b75ec1SPalash Bandyopadhyay return (ret != 1) ? -1 : 0; 5747b75ec1SPalash Bandyopadhyay } 5847b75ec1SPalash Bandyopadhyay 5947b75ec1SPalash Bandyopadhyay static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg) 6047b75ec1SPalash Bandyopadhyay { 6147b75ec1SPalash Bandyopadhyay int ret; 6247b75ec1SPalash Bandyopadhyay u8 b0[] = { reg }; 6347b75ec1SPalash Bandyopadhyay u8 b1[] = { 0 }; 6447b75ec1SPalash Bandyopadhyay 6547b75ec1SPalash Bandyopadhyay struct i2c_msg msg[] = { 6647b75ec1SPalash Bandyopadhyay {.addr = addr, .flags = 0, .buf = b0, .len = 1}, 67bda7f4eeSDevin Heitmueller {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1} 68bda7f4eeSDevin Heitmueller }; 6947b75ec1SPalash Bandyopadhyay 7047b75ec1SPalash Bandyopadhyay ret = i2c_transfer(state->i2c, msg, 2); 7147b75ec1SPalash Bandyopadhyay 7247b75ec1SPalash Bandyopadhyay if (ret != 2) 7347b75ec1SPalash Bandyopadhyay printk(KERN_ERR "%s: readreg error (ret == %i)\n", 7447b75ec1SPalash Bandyopadhyay __func__, ret); 7547b75ec1SPalash Bandyopadhyay return b1[0]; 7647b75ec1SPalash Bandyopadhyay } 7747b75ec1SPalash Bandyopadhyay 7847b75ec1SPalash Bandyopadhyay static int s5h1432_sleep(struct dvb_frontend *fe) 7947b75ec1SPalash Bandyopadhyay { 8047b75ec1SPalash Bandyopadhyay return 0; 8147b75ec1SPalash Bandyopadhyay } 8247b75ec1SPalash Bandyopadhyay 83bda7f4eeSDevin Heitmueller static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe, 84bda7f4eeSDevin Heitmueller u32 bandwidth) 8547b75ec1SPalash Bandyopadhyay { 8647b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = fe->demodulator_priv; 8747b75ec1SPalash Bandyopadhyay 8847b75ec1SPalash Bandyopadhyay u8 reg = 0; 8947b75ec1SPalash Bandyopadhyay 9047b75ec1SPalash Bandyopadhyay /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */ 9147b75ec1SPalash Bandyopadhyay reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E); 9247b75ec1SPalash Bandyopadhyay reg &= ~(0x0C); 9347b75ec1SPalash Bandyopadhyay switch (bandwidth) { 9447b75ec1SPalash Bandyopadhyay case 6: 9547b75ec1SPalash Bandyopadhyay reg |= 0x08; 9647b75ec1SPalash Bandyopadhyay break; 9747b75ec1SPalash Bandyopadhyay case 7: 9847b75ec1SPalash Bandyopadhyay reg |= 0x04; 9947b75ec1SPalash Bandyopadhyay break; 10047b75ec1SPalash Bandyopadhyay case 8: 10147b75ec1SPalash Bandyopadhyay reg |= 0x00; 10247b75ec1SPalash Bandyopadhyay break; 10347b75ec1SPalash Bandyopadhyay default: 10447b75ec1SPalash Bandyopadhyay return 0; 10547b75ec1SPalash Bandyopadhyay } 10647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg); 10747b75ec1SPalash Bandyopadhyay return 1; 10847b75ec1SPalash Bandyopadhyay } 10947b75ec1SPalash Bandyopadhyay 11047b75ec1SPalash Bandyopadhyay static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz) 11147b75ec1SPalash Bandyopadhyay { 11247b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = fe->demodulator_priv; 11347b75ec1SPalash Bandyopadhyay 11447b75ec1SPalash Bandyopadhyay switch (ifFreqHz) { 11547b75ec1SPalash Bandyopadhyay case TAIWAN_HI_IF_FREQ_44_MHZ: 11647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); 11747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); 11847b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15); 11947b75ec1SPalash Bandyopadhyay break; 12047b75ec1SPalash Bandyopadhyay case EUROPE_HI_IF_FREQ_36_MHZ: 12147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); 12247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); 12347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40); 12447b75ec1SPalash Bandyopadhyay break; 12547b75ec1SPalash Bandyopadhyay case IF_FREQ_6_MHZ: 12647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00); 12747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00); 12847b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0); 12947b75ec1SPalash Bandyopadhyay break; 13047b75ec1SPalash Bandyopadhyay case IF_FREQ_3point3_MHZ: 13147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); 13247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); 13347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); 13447b75ec1SPalash Bandyopadhyay break; 13547b75ec1SPalash Bandyopadhyay case IF_FREQ_3point5_MHZ: 13647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55); 13747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55); 13847b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED); 13947b75ec1SPalash Bandyopadhyay break; 14047b75ec1SPalash Bandyopadhyay case IF_FREQ_4_MHZ: 14147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA); 14247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA); 14347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA); 14447b75ec1SPalash Bandyopadhyay break; 14547b75ec1SPalash Bandyopadhyay default: 14647b75ec1SPalash Bandyopadhyay { 14747b75ec1SPalash Bandyopadhyay u32 value = 0; 14847b75ec1SPalash Bandyopadhyay value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 * 14947b75ec1SPalash Bandyopadhyay (u32) 32768) / (48 * 1000)); 150bda7f4eeSDevin Heitmueller printk(KERN_INFO 151bda7f4eeSDevin Heitmueller "Default IFFreq %d :reg value = 0x%x\n", 15247b75ec1SPalash Bandyopadhyay ifFreqHz, value); 15347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 15447b75ec1SPalash Bandyopadhyay (u8) value & 0xFF); 15547b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 15647b75ec1SPalash Bandyopadhyay (u8) (value >> 8) & 0xFF); 15747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 15847b75ec1SPalash Bandyopadhyay (u8) (value >> 16) & 0xFF); 15947b75ec1SPalash Bandyopadhyay break; 16047b75ec1SPalash Bandyopadhyay } 16147b75ec1SPalash Bandyopadhyay 16247b75ec1SPalash Bandyopadhyay } 16347b75ec1SPalash Bandyopadhyay 16447b75ec1SPalash Bandyopadhyay return 1; 16547b75ec1SPalash Bandyopadhyay } 16647b75ec1SPalash Bandyopadhyay 16747b75ec1SPalash Bandyopadhyay /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ 1686bfc3667SMauro Carvalho Chehab static int s5h1432_set_frontend(struct dvb_frontend *fe) 16947b75ec1SPalash Bandyopadhyay { 1706bfc3667SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 17147b75ec1SPalash Bandyopadhyay u32 dvb_bandwidth = 8; 17247b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = fe->demodulator_priv; 17347b75ec1SPalash Bandyopadhyay 17447b75ec1SPalash Bandyopadhyay if (p->frequency == state->current_frequency) { 17547b75ec1SPalash Bandyopadhyay /*current_frequency = p->frequency; */ 17647b75ec1SPalash Bandyopadhyay /*state->current_frequency = p->frequency; */ 17747b75ec1SPalash Bandyopadhyay } else { 17814d24d14SMauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 179bda7f4eeSDevin Heitmueller msleep(300); 18047b75ec1SPalash Bandyopadhyay s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); 1816bfc3667SMauro Carvalho Chehab switch (p->bandwidth_hz) { 1826bfc3667SMauro Carvalho Chehab case 6000000: 18347b75ec1SPalash Bandyopadhyay dvb_bandwidth = 6; 18447b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 18547b75ec1SPalash Bandyopadhyay break; 1866bfc3667SMauro Carvalho Chehab case 7000000: 18747b75ec1SPalash Bandyopadhyay dvb_bandwidth = 7; 18847b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 18947b75ec1SPalash Bandyopadhyay break; 1906bfc3667SMauro Carvalho Chehab case 8000000: 19147b75ec1SPalash Bandyopadhyay dvb_bandwidth = 8; 19247b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 19347b75ec1SPalash Bandyopadhyay break; 19447b75ec1SPalash Bandyopadhyay default: 19547b75ec1SPalash Bandyopadhyay return 0; 19647b75ec1SPalash Bandyopadhyay } 19714d24d14SMauro Carvalho Chehab /*fe->ops.tuner_ops.set_params(fe); */ 19847b75ec1SPalash Bandyopadhyay /*Soft Reset chip*/ 19947b75ec1SPalash Bandyopadhyay msleep(30); 20047b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); 20147b75ec1SPalash Bandyopadhyay msleep(30); 20247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); 20347b75ec1SPalash Bandyopadhyay 20447b75ec1SPalash Bandyopadhyay s5h1432_set_channel_bandwidth(fe, dvb_bandwidth); 2056bfc3667SMauro Carvalho Chehab switch (p->bandwidth_hz) { 2066bfc3667SMauro Carvalho Chehab case 6000000: 20747b75ec1SPalash Bandyopadhyay dvb_bandwidth = 6; 20847b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 20947b75ec1SPalash Bandyopadhyay break; 2106bfc3667SMauro Carvalho Chehab case 7000000: 21147b75ec1SPalash Bandyopadhyay dvb_bandwidth = 7; 21247b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 21347b75ec1SPalash Bandyopadhyay break; 2146bfc3667SMauro Carvalho Chehab case 8000000: 21547b75ec1SPalash Bandyopadhyay dvb_bandwidth = 8; 21647b75ec1SPalash Bandyopadhyay s5h1432_set_IF(fe, IF_FREQ_4_MHZ); 21747b75ec1SPalash Bandyopadhyay break; 21847b75ec1SPalash Bandyopadhyay default: 21947b75ec1SPalash Bandyopadhyay return 0; 22047b75ec1SPalash Bandyopadhyay } 22114d24d14SMauro Carvalho Chehab /*fe->ops.tuner_ops.set_params(fe); */ 22247b75ec1SPalash Bandyopadhyay /*Soft Reset chip*/ 22347b75ec1SPalash Bandyopadhyay msleep(30); 22447b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); 22547b75ec1SPalash Bandyopadhyay msleep(30); 22647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); 22747b75ec1SPalash Bandyopadhyay 22847b75ec1SPalash Bandyopadhyay } 22947b75ec1SPalash Bandyopadhyay 23047b75ec1SPalash Bandyopadhyay state->current_frequency = p->frequency; 23147b75ec1SPalash Bandyopadhyay 23247b75ec1SPalash Bandyopadhyay return 0; 23347b75ec1SPalash Bandyopadhyay } 23447b75ec1SPalash Bandyopadhyay 23547b75ec1SPalash Bandyopadhyay static int s5h1432_init(struct dvb_frontend *fe) 23647b75ec1SPalash Bandyopadhyay { 23747b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = fe->demodulator_priv; 23847b75ec1SPalash Bandyopadhyay 23947b75ec1SPalash Bandyopadhyay u8 reg = 0; 24047b75ec1SPalash Bandyopadhyay state->current_frequency = 0; 24147b75ec1SPalash Bandyopadhyay printk(KERN_INFO " s5h1432_init().\n"); 24247b75ec1SPalash Bandyopadhyay 24347b75ec1SPalash Bandyopadhyay /*Set VSB mode as default, this also does a soft reset */ 24447b75ec1SPalash Bandyopadhyay /*Initialize registers */ 24547b75ec1SPalash Bandyopadhyay 24647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8); 24747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01); 24847b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70); 24947b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80); 25047b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D); 25147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30); 25247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20); 25347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B); 25447b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40); 25547b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84); 25647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a); 25747b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3); 25847b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50); 25947b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c); 26047b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10); 26147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c); 26247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00); 26347b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94); 26447b75ec1SPalash Bandyopadhyay /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */ 26547b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00); 26647b75ec1SPalash Bandyopadhyay 26747b75ec1SPalash Bandyopadhyay /*For NXP tuner*/ 26847b75ec1SPalash Bandyopadhyay 26947b75ec1SPalash Bandyopadhyay /*Set 3.3MHz as default IF frequency */ 27047b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66); 27147b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66); 27247b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE); 27347b75ec1SPalash Bandyopadhyay /* Set reg 0x1E to get the full dynamic range */ 27447b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31); 27547b75ec1SPalash Bandyopadhyay 27647b75ec1SPalash Bandyopadhyay /* Mode setting in demod */ 27747b75ec1SPalash Bandyopadhyay reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42); 27847b75ec1SPalash Bandyopadhyay reg |= 0x80; 27947b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg); 28047b75ec1SPalash Bandyopadhyay /* Serial mode */ 28147b75ec1SPalash Bandyopadhyay 28247b75ec1SPalash Bandyopadhyay /* Soft Reset chip */ 28347b75ec1SPalash Bandyopadhyay 28447b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a); 28547b75ec1SPalash Bandyopadhyay msleep(30); 28647b75ec1SPalash Bandyopadhyay s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b); 28747b75ec1SPalash Bandyopadhyay 28847b75ec1SPalash Bandyopadhyay 28947b75ec1SPalash Bandyopadhyay return 0; 29047b75ec1SPalash Bandyopadhyay } 29147b75ec1SPalash Bandyopadhyay 2920df289a2SMauro Carvalho Chehab static int s5h1432_read_status(struct dvb_frontend *fe, enum fe_status *status) 29347b75ec1SPalash Bandyopadhyay { 29447b75ec1SPalash Bandyopadhyay return 0; 29547b75ec1SPalash Bandyopadhyay } 29647b75ec1SPalash Bandyopadhyay 29747b75ec1SPalash Bandyopadhyay static int s5h1432_read_signal_strength(struct dvb_frontend *fe, 29847b75ec1SPalash Bandyopadhyay u16 *signal_strength) 29947b75ec1SPalash Bandyopadhyay { 30047b75ec1SPalash Bandyopadhyay return 0; 30147b75ec1SPalash Bandyopadhyay } 30247b75ec1SPalash Bandyopadhyay 30347b75ec1SPalash Bandyopadhyay static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr) 30447b75ec1SPalash Bandyopadhyay { 30547b75ec1SPalash Bandyopadhyay return 0; 30647b75ec1SPalash Bandyopadhyay } 30747b75ec1SPalash Bandyopadhyay 30847b75ec1SPalash Bandyopadhyay static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 30947b75ec1SPalash Bandyopadhyay { 31047b75ec1SPalash Bandyopadhyay 31147b75ec1SPalash Bandyopadhyay return 0; 31247b75ec1SPalash Bandyopadhyay } 31347b75ec1SPalash Bandyopadhyay 31447b75ec1SPalash Bandyopadhyay static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber) 31547b75ec1SPalash Bandyopadhyay { 31647b75ec1SPalash Bandyopadhyay return 0; 31747b75ec1SPalash Bandyopadhyay } 31847b75ec1SPalash Bandyopadhyay 31947b75ec1SPalash Bandyopadhyay static int s5h1432_get_tune_settings(struct dvb_frontend *fe, 32047b75ec1SPalash Bandyopadhyay struct dvb_frontend_tune_settings *tune) 32147b75ec1SPalash Bandyopadhyay { 32247b75ec1SPalash Bandyopadhyay return 0; 32347b75ec1SPalash Bandyopadhyay } 32447b75ec1SPalash Bandyopadhyay 32547b75ec1SPalash Bandyopadhyay static void s5h1432_release(struct dvb_frontend *fe) 32647b75ec1SPalash Bandyopadhyay { 32747b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = fe->demodulator_priv; 32847b75ec1SPalash Bandyopadhyay kfree(state); 32947b75ec1SPalash Bandyopadhyay } 33047b75ec1SPalash Bandyopadhyay 331bd336e63SMax Kellermann static const struct dvb_frontend_ops s5h1432_ops; 33247b75ec1SPalash Bandyopadhyay 33347b75ec1SPalash Bandyopadhyay struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, 33447b75ec1SPalash Bandyopadhyay struct i2c_adapter *i2c) 33547b75ec1SPalash Bandyopadhyay { 33647b75ec1SPalash Bandyopadhyay struct s5h1432_state *state = NULL; 33747b75ec1SPalash Bandyopadhyay 33847b75ec1SPalash Bandyopadhyay printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n"); 33947b75ec1SPalash Bandyopadhyay /* allocate memory for the internal state */ 34047b75ec1SPalash Bandyopadhyay state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL); 34147aab4abSPeter Senna Tschudin if (!state) 34247aab4abSPeter Senna Tschudin return NULL; 34347b75ec1SPalash Bandyopadhyay 34447b75ec1SPalash Bandyopadhyay /* setup the state */ 34547b75ec1SPalash Bandyopadhyay state->config = config; 34647b75ec1SPalash Bandyopadhyay state->i2c = i2c; 34747b75ec1SPalash Bandyopadhyay state->current_modulation = QAM_16; 34847b75ec1SPalash Bandyopadhyay state->inversion = state->config->inversion; 34947b75ec1SPalash Bandyopadhyay 35047b75ec1SPalash Bandyopadhyay /* create dvb_frontend */ 35147b75ec1SPalash Bandyopadhyay memcpy(&state->frontend.ops, &s5h1432_ops, 35247b75ec1SPalash Bandyopadhyay sizeof(struct dvb_frontend_ops)); 35347b75ec1SPalash Bandyopadhyay 35447b75ec1SPalash Bandyopadhyay state->frontend.demodulator_priv = state; 35547b75ec1SPalash Bandyopadhyay 35647b75ec1SPalash Bandyopadhyay return &state->frontend; 35747b75ec1SPalash Bandyopadhyay } 35847b75ec1SPalash Bandyopadhyay EXPORT_SYMBOL(s5h1432_attach); 35947b75ec1SPalash Bandyopadhyay 360bd336e63SMax Kellermann static const struct dvb_frontend_ops s5h1432_ops = { 361533b673bSMauro Carvalho Chehab .delsys = { SYS_DVBT }, 36247b75ec1SPalash Bandyopadhyay .info = { 36347b75ec1SPalash Bandyopadhyay .name = "Samsung s5h1432 DVB-T Frontend", 364f1b1eabfSMauro Carvalho Chehab .frequency_min_hz = 177 * MHz, 365f1b1eabfSMauro Carvalho Chehab .frequency_max_hz = 858 * MHz, 366f1b1eabfSMauro Carvalho Chehab .frequency_stepsize_hz = 166666, 36747b75ec1SPalash Bandyopadhyay .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 36847b75ec1SPalash Bandyopadhyay FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 36947b75ec1SPalash Bandyopadhyay FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 37047b75ec1SPalash Bandyopadhyay FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | 371bda7f4eeSDevin Heitmueller FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER}, 37247b75ec1SPalash Bandyopadhyay 37347b75ec1SPalash Bandyopadhyay .init = s5h1432_init, 37447b75ec1SPalash Bandyopadhyay .sleep = s5h1432_sleep, 3756bfc3667SMauro Carvalho Chehab .set_frontend = s5h1432_set_frontend, 37647b75ec1SPalash Bandyopadhyay .get_tune_settings = s5h1432_get_tune_settings, 37747b75ec1SPalash Bandyopadhyay .read_status = s5h1432_read_status, 37847b75ec1SPalash Bandyopadhyay .read_ber = s5h1432_read_ber, 37947b75ec1SPalash Bandyopadhyay .read_signal_strength = s5h1432_read_signal_strength, 38047b75ec1SPalash Bandyopadhyay .read_snr = s5h1432_read_snr, 38147b75ec1SPalash Bandyopadhyay .read_ucblocks = s5h1432_read_ucblocks, 38247b75ec1SPalash Bandyopadhyay .release = s5h1432_release, 38347b75ec1SPalash Bandyopadhyay }; 38447b75ec1SPalash Bandyopadhyay 38547b75ec1SPalash Bandyopadhyay module_param(debug, int, 0644); 38647b75ec1SPalash Bandyopadhyay MODULE_PARM_DESC(debug, "Enable verbose debug messages"); 38747b75ec1SPalash Bandyopadhyay 38847b75ec1SPalash Bandyopadhyay MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver"); 38947b75ec1SPalash Bandyopadhyay MODULE_AUTHOR("Bill Liu"); 39047b75ec1SPalash Bandyopadhyay MODULE_LICENSE("GPL"); 391