Skip to content

Commit c52a1c5

Browse files
vadimp-nvidiawsakernel
authored andcommitted
i2c: mux: mlxcpld: Extend driver to support word address space devices
Extend driver to allow I2C routing control through CPLD devices with word address space. Till now only CPLD devices with byte address space have been supported. Signed-off-by: Vadim Pasternak <[email protected]> Reviewed-by: Michael Shych <[email protected]> Acked-by: Peter Rosin <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent cae5216 commit c52a1c5

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

drivers/i2c/muxes/i2c-mux-mlxcpld.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,39 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
6363
struct mlxcpld_mux *mux, u32 val)
6464
{
6565
struct i2c_client *client = mux->client;
66-
union i2c_smbus_data data = { .byte = val };
67-
68-
return __i2c_smbus_xfer(adap, client->addr, client->flags,
69-
I2C_SMBUS_WRITE, mux->pdata.sel_reg_addr,
70-
I2C_SMBUS_BYTE_DATA, &data);
66+
union i2c_smbus_data data;
67+
struct i2c_msg msg;
68+
u8 buf[3];
69+
70+
switch (mux->pdata.reg_size) {
71+
case 1:
72+
data.byte = val;
73+
return __i2c_smbus_xfer(adap, client->addr, client->flags,
74+
I2C_SMBUS_WRITE, mux->pdata.sel_reg_addr,
75+
I2C_SMBUS_BYTE_DATA, &data);
76+
case 2:
77+
buf[0] = mux->pdata.sel_reg_addr >> 8;
78+
buf[1] = mux->pdata.sel_reg_addr;
79+
buf[2] = val;
80+
msg.addr = client->addr;
81+
msg.buf = buf;
82+
msg.len = mux->pdata.reg_size + 1;
83+
msg.flags = 0;
84+
return __i2c_transfer(adap, &msg, 1);
85+
default:
86+
return -EINVAL;
87+
}
7188
}
7289

7390
static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
7491
{
7592
struct mlxcpld_mux *mux = i2c_mux_priv(muxc);
76-
u32 regval = chan + 1;
93+
u32 regval = chan;
7794
int err = 0;
7895

96+
if (mux->pdata.reg_size == 1)
97+
regval += 1;
98+
7999
/* Only select the channel if its different from the last channel */
80100
if (mux->last_val != regval) {
81101
err = mlxcpld_mux_reg_write(muxc->parent, mux, regval);
@@ -103,12 +123,23 @@ static int mlxcpld_mux_probe(struct platform_device *pdev)
103123
struct i2c_mux_core *muxc;
104124
struct mlxcpld_mux *data;
105125
int num, err;
126+
u32 func;
106127

107128
if (!pdata)
108129
return -EINVAL;
109130

110-
if (!i2c_check_functionality(client->adapter,
111-
I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
131+
switch (pdata->reg_size) {
132+
case 1:
133+
func = I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
134+
break;
135+
case 2:
136+
func = I2C_FUNC_I2C;
137+
break;
138+
default:
139+
return -EINVAL;
140+
}
141+
142+
if (!i2c_check_functionality(client->adapter, func))
112143
return -ENODEV;
113144

114145
muxc = i2c_mux_alloc(client->adapter, &pdev->dev, CPLD_MUX_MAX_NCHANS,

include/linux/platform_data/mlxcpld.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
* @chan_ids - channels array
1515
* @num_adaps - number of adapters
1616
* @sel_reg_addr - mux select register offset in CPLD space
17+
* @reg_size: register size in bytes
1718
*/
1819
struct mlxcpld_mux_plat_data {
1920
int *chan_ids;
2021
int num_adaps;
2122
int sel_reg_addr;
23+
u8 reg_size;
2224
};
2325

2426
#endif /* _LINUX_I2C_MLXCPLD_H */

0 commit comments

Comments
 (0)