3 #include "dibx000_common.h"
6 module_param(debug
, int, 0644);
7 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
9 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
11 static int dibx000_write_word(struct dibx000_i2c_master
*mst
, u16 reg
, u16 val
)
14 (reg
>> 8) & 0xff, reg
& 0xff,
15 (val
>> 8) & 0xff, val
& 0xff,
17 struct i2c_msg msg
= {
18 .addr
= mst
->i2c_addr
,.flags
= 0,.buf
= b
,.len
= 4
20 return i2c_transfer(mst
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
24 static int dibx000_i2c_select_interface(struct dibx000_i2c_master
*mst
,
25 enum dibx000_i2c_interface intf
)
27 if (mst
->device_rev
> DIB3000MC
&& mst
->selected_interface
!= intf
) {
28 dprintk("selecting interface: %d\n", intf
);
29 mst
->selected_interface
= intf
;
30 return dibx000_write_word(mst
, mst
->base_reg
+ 4, intf
);
35 static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master
*mst
, u8 tx
[4],
42 val
= addr
<< 8; // bit 7 = use master or not, if 0, the gate is open
46 if (mst
->device_rev
> DIB7000
)
49 tx
[0] = (((mst
->base_reg
+ 1) >> 8) & 0xff);
50 tx
[1] = ((mst
->base_reg
+ 1) & 0xff);
57 static u32
dibx000_i2c_func(struct i2c_adapter
*adapter
)
62 static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter
*i2c_adap
,
63 struct i2c_msg msg
[], int num
)
65 struct dibx000_i2c_master
*mst
= i2c_get_adapdata(i2c_adap
);
66 struct i2c_msg m
[2 + num
];
67 u8 tx_open
[4], tx_close
[4];
69 memset(m
, 0, sizeof(struct i2c_msg
) * (2 + num
));
71 dibx000_i2c_select_interface(mst
, DIBX000_I2C_INTERFACE_TUNER
);
73 dibx000_i2c_gate_ctrl(mst
, tx_open
, msg
[0].addr
, 1);
74 m
[0].addr
= mst
->i2c_addr
;
78 memcpy(&m
[1], msg
, sizeof(struct i2c_msg
) * num
);
80 dibx000_i2c_gate_ctrl(mst
, tx_close
, 0, 0);
81 m
[num
+ 1].addr
= mst
->i2c_addr
;
82 m
[num
+ 1].buf
= tx_close
;
85 return i2c_transfer(mst
->i2c_adap
, m
, 2 + num
) == 2 + num
? num
: -EIO
;
88 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo
= {
89 .master_xfer
= dibx000_i2c_gated_tuner_xfer
,
90 .functionality
= dibx000_i2c_func
,
93 struct i2c_adapter
*dibx000_get_i2c_adapter(struct dibx000_i2c_master
*mst
,
94 enum dibx000_i2c_interface intf
,
97 struct i2c_adapter
*i2c
= NULL
;
100 case DIBX000_I2C_INTERFACE_TUNER
:
102 i2c
= &mst
->gated_tuner_i2c_adap
;
105 printk(KERN_ERR
"DiBX000: incorrect I2C interface selected\n");
112 EXPORT_SYMBOL(dibx000_get_i2c_adapter
);
114 void dibx000_reset_i2c_master(struct dibx000_i2c_master
*mst
)
116 /* initialize the i2c-master by closing the gate */
118 struct i2c_msg m
= {.addr
= mst
->i2c_addr
,.buf
= tx
,.len
= 4 };
120 dibx000_i2c_gate_ctrl(mst
, tx
, 0, 0);
121 i2c_transfer(mst
->i2c_adap
, &m
, 1);
122 mst
->selected_interface
= 0xff; // the first time force a select of the I2C
123 dibx000_i2c_select_interface(mst
, DIBX000_I2C_INTERFACE_TUNER
);
126 EXPORT_SYMBOL(dibx000_reset_i2c_master
);
128 static int i2c_adapter_init(struct i2c_adapter
*i2c_adap
,
129 struct i2c_algorithm
*algo
, const char *name
,
130 struct dibx000_i2c_master
*mst
)
132 strncpy(i2c_adap
->name
, name
, sizeof(i2c_adap
->name
));
133 i2c_adap
->class = I2C_CLASS_TV_DIGITAL
, i2c_adap
->algo
= algo
;
134 i2c_adap
->algo_data
= NULL
;
135 i2c_set_adapdata(i2c_adap
, mst
);
136 if (i2c_add_adapter(i2c_adap
) < 0)
141 int dibx000_init_i2c_master(struct dibx000_i2c_master
*mst
, u16 device_rev
,
142 struct i2c_adapter
*i2c_adap
, u8 i2c_addr
)
145 struct i2c_msg m
= {.addr
= i2c_addr
>> 1,.buf
= tx
,.len
= 4 };
147 mst
->device_rev
= device_rev
;
148 mst
->i2c_adap
= i2c_adap
;
149 mst
->i2c_addr
= i2c_addr
>> 1;
151 if (device_rev
== DIB7000P
|| device_rev
== DIB8000
)
152 mst
->base_reg
= 1024;
157 (&mst
->gated_tuner_i2c_adap
, &dibx000_i2c_gated_tuner_algo
,
158 "DiBX000 tuner I2C bus", mst
) != 0)
160 "DiBX000: could not initialize the tuner i2c_adapter\n");
162 /* initialize the i2c-master by closing the gate */
163 dibx000_i2c_gate_ctrl(mst
, tx
, 0, 0);
165 return i2c_transfer(i2c_adap
, &m
, 1) == 1;
168 EXPORT_SYMBOL(dibx000_init_i2c_master
);
170 void dibx000_exit_i2c_master(struct dibx000_i2c_master
*mst
)
172 i2c_del_adapter(&mst
->gated_tuner_i2c_adap
);
175 EXPORT_SYMBOL(dibx000_exit_i2c_master
);
177 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
178 MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
179 MODULE_LICENSE("GPL");