Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (9364): adding sharp s921 ISDB-T driver

s921_module.c:
wrapper for the dvb frontend interface
s921_core.c:
core s921 1seg ISDB-T driver, everything is set to auto as much as possible
in order to not require certain parameters which currently cannot be passed
to the ISDB-T chip.

ISDB-T support can be tested using dvbscan, dvbstream/snoop and mplayer
Tested 1seg H264/aac stream with this driver using a custom linux
ISDB-T player

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Markus Rechberger and committed by
Mauro Carvalho Chehab
aa56cb9d 2c5aacc6

+571
+3
drivers/media/video/empia/sharp/Makefile
··· 1 + s921-objs := s921_module.o s921_core.o 2 + 3 + obj-m += s921.o
+215
drivers/media/video/empia/sharp/s921_core.c
··· 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> 11 + #include "s921_core.h" 12 + 13 + static int s921_isdb_init(struct s921_isdb_t *dev); 14 + static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); 15 + static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); 16 + static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); 17 + 18 + static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, 19 + 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 20 + 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, 21 + 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, 22 + 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, 23 + 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, 24 + 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, 25 + 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, 26 + 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, 27 + 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, 28 + 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, 29 + 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, 30 + 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, 31 + 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, 32 + 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, 33 + 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, 34 + 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, 35 + 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, 36 + 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, 37 + 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, 38 + 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, 39 + 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, 40 + 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, 41 + 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, 42 + 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, 43 + 0xf8, 0xd7 }; 44 + 45 + static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, 46 + 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, 47 + 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, 48 + 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, 49 + 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, 50 + 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, 51 + 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, 52 + 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, 53 + 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, 54 + 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, 55 + 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, 56 + 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, 57 + 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, 58 + 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, 59 + 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, 60 + 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, 61 + 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; 62 + 63 + int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { 64 + switch(cmd) { 65 + case ISDB_T_CMD_INIT: 66 + s921_isdb_init(dev); 67 + break; 68 + case ISDB_T_CMD_SET_PARAM: 69 + s921_isdb_set_parameters(dev, data); 70 + break; 71 + case ISDB_T_CMD_TUNE: 72 + s921_isdb_tune(dev, data); 73 + break; 74 + case ISDB_T_CMD_GET_STATUS: 75 + s921_isdb_get_status(dev, data); 76 + break; 77 + default: 78 + printk("unhandled command\n"); 79 + return -EINVAL; 80 + } 81 + return 0; 82 + } 83 + 84 + static int s921_isdb_init(struct s921_isdb_t *dev) { 85 + unsigned int i; 86 + unsigned int ret; 87 + printk("isdb_init\n"); 88 + for (i = 0; i < sizeof(init_table); i+=2) { 89 + ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); 90 + if (ret != 0) { 91 + printk("i2c write failed\n"); 92 + return ret; 93 + } 94 + } 95 + return 0; 96 + } 97 + 98 + static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { 99 + 100 + int ret; 101 + /* auto is sufficient for now, lateron this should be reflected in an extra interface */ 102 + 103 + 104 + 105 + ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); 106 + ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); 107 + 108 + if (ret < 0) 109 + return -EINVAL; 110 + 111 + ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); 112 + if (ret < 0) 113 + return -EINVAL; 114 + 115 + ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); 116 + if (ret < 0) 117 + return -EINVAL; 118 + 119 + ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); 120 + if (ret < 0) 121 + return -EINVAL; 122 + 123 + ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); 124 + if (ret < 0) 125 + return -EINVAL; 126 + 127 + ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); 128 + if (ret < 0) 129 + return -EINVAL; 130 + 131 + return E_OK; 132 + } 133 + 134 + static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { 135 + 136 + int ret; 137 + int index; 138 + 139 + index = (params->frequency - 473143000)/6000000; 140 + 141 + if (index > 48) { 142 + return -EINVAL; 143 + } 144 + 145 + dev->i2c_write(dev->priv_dev, 0x47, 0x60); 146 + 147 + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); 148 + if (ret < 0) 149 + return -EINVAL; 150 + 151 + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); 152 + if (ret < 0) 153 + return -EINVAL; 154 + 155 + ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); 156 + if (ret < 0) 157 + return -EINVAL; 158 + 159 + ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); 160 + if (ret < 0) 161 + return -EINVAL; 162 + 163 + ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); 164 + if (ret < 0) 165 + return -EINVAL; 166 + 167 + ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); 168 + if (ret < 0) 169 + return -EINVAL; 170 + 171 + ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); 172 + if (ret < 0) 173 + return -EINVAL; 174 + 175 + ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); 176 + if (ret < 0) 177 + return -EINVAL; 178 + 179 + ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); 180 + if (ret < 0) 181 + return -EINVAL; 182 + 183 + ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); 184 + if (ret < 0) 185 + return -EINVAL; 186 + 187 + ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); 188 + if (ret < 0) 189 + return -EINVAL; 190 + 191 + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); 192 + if (ret < 0) 193 + return -EINVAL; 194 + 195 + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); 196 + if (ret < 0) 197 + return -EINVAL; 198 + 199 + dev->i2c_write(dev->priv_dev, 0x01, 0x40); 200 + return 0; 201 + } 202 + 203 + static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { 204 + unsigned int *ret = (unsigned int*)data; 205 + u8 ifagc_dt; 206 + u8 rfagc_dt; 207 + 208 + mdelay(10); 209 + ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); 210 + rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); 211 + if (rfagc_dt == 0x40) { 212 + *ret = 1; 213 + } 214 + return 0; 215 + }
+114
drivers/media/video/empia/sharp/s921_core.h
··· 1 + #ifndef _S921_CORE_H 2 + #define _S921_CORE_H 3 + //#define u8 unsigned int 4 + //#define u32 unsigned int 5 + 6 + 7 + 8 + //#define EINVAL -1 9 + #define E_OK 0 10 + 11 + struct s921_isdb_t { 12 + void *priv_dev; 13 + int (*i2c_write)(void *dev, u8 reg, u8 val); 14 + int (*i2c_read)(void *dev, u8 reg); 15 + }; 16 + 17 + #define ISDB_T_CMD_INIT 0 18 + #define ISDB_T_CMD_SET_PARAM 1 19 + #define ISDB_T_CMD_TUNE 2 20 + #define ISDB_T_CMD_GET_STATUS 3 21 + 22 + struct s921_isdb_t_tune_params { 23 + u32 frequency; 24 + }; 25 + 26 + struct s921_isdb_t_status { 27 + }; 28 + 29 + struct s921_isdb_t_transmission_mode_params { 30 + u8 mode; 31 + u8 layer_a_mode; 32 + #define ISDB_T_LA_MODE_1 0 33 + #define ISDB_T_LA_MODE_2 1 34 + #define ISDB_T_LA_MODE_3 2 35 + u8 layer_a_carrier_modulation; 36 + #define ISDB_T_LA_CM_DQPSK 0 37 + #define ISDB_T_LA_CM_QPSK 1 38 + #define ISDB_T_LA_CM_16QAM 2 39 + #define ISDB_T_LA_CM_64QAM 3 40 + #define ISDB_T_LA_CM_NOLAYER 4 41 + u8 layer_a_code_rate; 42 + #define ISDB_T_LA_CR_1_2 0 43 + #define ISDB_T_LA_CR_2_3 1 44 + #define ISDB_T_LA_CR_3_4 2 45 + #define ISDB_T_LA_CR_5_6 4 46 + #define ISDB_T_LA_CR_7_8 8 47 + #define ISDB_T_LA_CR_NOLAYER 16 48 + u8 layer_a_time_interleave; 49 + #define ISDB_T_LA_TI_0 0 50 + #define ISDB_T_LA_TI_1 1 51 + #define ISDB_T_LA_TI_2 2 52 + #define ISDB_T_LA_TI_4 4 53 + #define ISDB_T_LA_TI_8 8 54 + #define ISDB_T_LA_TI_16 16 55 + #define ISDB_T_LA_TI_32 32 56 + u8 layer_a_nseg; 57 + 58 + u8 layer_b_mode; 59 + #define ISDB_T_LB_MODE_1 0 60 + #define ISDB_T_LB_MODE_2 1 61 + #define ISDB_T_LB_MODE_3 2 62 + u8 layer_b_carrier_modulation; 63 + #define ISDB_T_LB_CM_DQPSK 0 64 + #define ISDB_T_LB_CM_QPSK 1 65 + #define ISDB_T_LB_CM_16QAM 2 66 + #define ISDB_T_LB_CM_64QAM 3 67 + #define ISDB_T_LB_CM_NOLAYER 4 68 + u8 layer_b_code_rate; 69 + #define ISDB_T_LB_CR_1_2 0 70 + #define ISDB_T_LB_CR_2_3 1 71 + #define ISDB_T_LB_CR_3_4 2 72 + #define ISDB_T_LB_CR_5_6 4 73 + #define ISDB_T_LB_CR_7_8 8 74 + #define ISDB_T_LB_CR_NOLAYER 16 75 + u8 layer_b_time_interleave; 76 + #define ISDB_T_LB_TI_0 0 77 + #define ISDB_T_LB_TI_1 1 78 + #define ISDB_T_LB_TI_2 2 79 + #define ISDB_T_LB_TI_4 4 80 + #define ISDB_T_LB_TI_8 8 81 + #define ISDB_T_LB_TI_16 16 82 + #define ISDB_T_LB_TI_32 32 83 + u8 layer_b_nseg; 84 + 85 + u8 layer_c_mode; 86 + #define ISDB_T_LC_MODE_1 0 87 + #define ISDB_T_LC_MODE_2 1 88 + #define ISDB_T_LC_MODE_3 2 89 + u8 layer_c_carrier_modulation; 90 + #define ISDB_T_LC_CM_DQPSK 0 91 + #define ISDB_T_LC_CM_QPSK 1 92 + #define ISDB_T_LC_CM_16QAM 2 93 + #define ISDB_T_LC_CM_64QAM 3 94 + #define ISDB_T_LC_CM_NOLAYER 4 95 + u8 layer_c_code_rate; 96 + #define ISDB_T_LC_CR_1_2 0 97 + #define ISDB_T_LC_CR_2_3 1 98 + #define ISDB_T_LC_CR_3_4 2 99 + #define ISDB_T_LC_CR_5_6 4 100 + #define ISDB_T_LC_CR_7_8 8 101 + #define ISDB_T_LC_CR_NOLAYER 16 102 + u8 layer_c_time_interleave; 103 + #define ISDB_T_LC_TI_0 0 104 + #define ISDB_T_LC_TI_1 1 105 + #define ISDB_T_LC_TI_2 2 106 + #define ISDB_T_LC_TI_4 4 107 + #define ISDB_T_LC_TI_8 8 108 + #define ISDB_T_LC_TI_16 16 109 + #define ISDB_T_LC_TI_32 32 110 + u8 layer_c_nseg; 111 + }; 112 + 113 + int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); 114 + #endif
+190
drivers/media/video/empia/sharp/s921_module.c
··· 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, &params); 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 = &reg, .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");
+49
drivers/media/video/empia/sharp/s921_module.h
··· 1 + /* 2 + * Driver for DVB-T s921 demodulator 3 + * 4 + * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= 20 + */ 21 + 22 + #ifndef S921_MODULE_H 23 + #define S921_MODULE_H 24 + 25 + #include <linux/dvb/frontend.h> 26 + #include "s921_core.h" 27 + 28 + int s921_isdb_init(struct s921_isdb_t *dev); 29 + int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); 30 + 31 + struct s921_config 32 + { 33 + /* demodulator's I2C address */ 34 + u8 i2c_address; 35 + }; 36 + 37 + #if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) 38 + extern struct dvb_frontend* s921_attach(const struct s921_config *config, 39 + struct i2c_adapter *i2c); 40 + #else 41 + static inline struct dvb_frontend* s921_attach(const struct s921_config *config, 42 + struct i2c_adapter *i2c) 43 + { 44 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 45 + return NULL; 46 + } 47 + #endif /* CONFIG_DVB_S921 */ 48 + 49 + #endif /* S921_H */