1 // SPDX-License-Identifier: GPL-2.0-only
5 * Derived from cx18-i2c.c
7 * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
11 #include "cobalt-driver.h"
12 #include "cobalt-i2c.h"
14 struct cobalt_i2c_regs
{
15 /* Clock prescaler register lo-byte */
18 /* Clock prescaler register high-byte */
21 /* Control register */
24 /* Transmit/Receive register */
27 /* Command and Status register */
32 /* CTR[7:0] - Control register */
34 /* I2C Core enable bit */
35 #define M00018_CTR_BITMAP_EN_MSK (1 << 7)
37 /* I2C Core interrupt enable bit */
38 #define M00018_CTR_BITMAP_IEN_MSK (1 << 6)
40 /* CR[7:0] - Command register */
42 /* I2C start condition */
43 #define M00018_CR_BITMAP_STA_MSK (1 << 7)
45 /* I2C stop condition */
46 #define M00018_CR_BITMAP_STO_MSK (1 << 6)
48 /* I2C read from slave */
49 #define M00018_CR_BITMAP_RD_MSK (1 << 5)
51 /* I2C write to slave */
52 #define M00018_CR_BITMAP_WR_MSK (1 << 4)
55 #define M00018_CR_BITMAP_ACK_MSK (1 << 3)
57 /* I2C Interrupt ack */
58 #define M00018_CR_BITMAP_IACK_MSK (1 << 0)
60 /* SR[7:0] - Status register */
62 /* Receive acknowledge from slave */
63 #define M00018_SR_BITMAP_RXACK_MSK (1 << 7)
65 /* Busy, I2C bus busy (as defined by start / stop bits) */
66 #define M00018_SR_BITMAP_BUSY_MSK (1 << 6)
68 /* Arbitration lost - core lost arbitration */
69 #define M00018_SR_BITMAP_AL_MSK (1 << 5)
71 /* Transfer in progress */
72 #define M00018_SR_BITMAP_TIP_MSK (1 << 1)
75 #define M00018_SR_BITMAP_IF_MSK (1 << 0)
77 /* Frequency, in Hz */
78 #define I2C_FREQUENCY 400000
79 #define ALT_CPU_FREQ 83333333
81 static struct cobalt_i2c_regs __iomem
*
82 cobalt_i2c_regs(struct cobalt
*cobalt
, unsigned idx
)
87 return (struct cobalt_i2c_regs __iomem
*)
88 (cobalt
->bar1
+ COBALT_I2C_0_BASE
);
90 return (struct cobalt_i2c_regs __iomem
*)
91 (cobalt
->bar1
+ COBALT_I2C_1_BASE
);
93 return (struct cobalt_i2c_regs __iomem
*)
94 (cobalt
->bar1
+ COBALT_I2C_2_BASE
);
96 return (struct cobalt_i2c_regs __iomem
*)
97 (cobalt
->bar1
+ COBALT_I2C_3_BASE
);
99 return (struct cobalt_i2c_regs __iomem
*)
100 (cobalt
->bar1
+ COBALT_I2C_HSMA_BASE
);
104 /* Do low-level i2c byte transfer.
105 * Returns -1 in case of an error or 0 otherwise.
107 static int cobalt_tx_bytes(struct cobalt_i2c_regs __iomem
*regs
,
108 struct i2c_adapter
*adap
, bool start
, bool stop
,
111 unsigned long start_time
;
116 for (i
= 0; i
< len
; i
++) {
118 iowrite8(data
[i
], ®s
->txr_rxr
);
121 if (i
== 0 && start
) {
123 cmd
= M00018_CR_BITMAP_WR_MSK
|
124 M00018_CR_BITMAP_STA_MSK
;
125 } else if (i
== len
- 1 && stop
) {
127 cmd
= M00018_CR_BITMAP_WR_MSK
|
128 M00018_CR_BITMAP_STO_MSK
;
131 cmd
= M00018_CR_BITMAP_WR_MSK
;
134 /* Execute command */
135 iowrite8(cmd
, ®s
->cr_sr
);
137 /* Wait for transfer to complete (TIP = 0) */
138 start_time
= jiffies
;
139 status
= ioread8(®s
->cr_sr
);
140 while (status
& M00018_SR_BITMAP_TIP_MSK
) {
141 if (time_after(jiffies
, start_time
+ adap
->timeout
))
144 status
= ioread8(®s
->cr_sr
);
148 if (status
& M00018_SR_BITMAP_RXACK_MSK
) {
153 /* Verify arbitration */
154 if (status
& M00018_SR_BITMAP_AL_MSK
) {
155 /* Arbitration lost! */
162 /* Do low-level i2c byte read.
163 * Returns -1 in case of an error or 0 otherwise.
165 static int cobalt_rx_bytes(struct cobalt_i2c_regs __iomem
*regs
,
166 struct i2c_adapter
*adap
, bool start
, bool stop
,
169 unsigned long start_time
;
174 for (i
= 0; i
< len
; i
++) {
176 if (i
== 0 && start
) {
178 cmd
= M00018_CR_BITMAP_RD_MSK
|
179 M00018_CR_BITMAP_STA_MSK
;
180 } else if (i
== len
- 1 && stop
) {
182 cmd
= M00018_CR_BITMAP_RD_MSK
|
183 M00018_CR_BITMAP_STO_MSK
;
186 cmd
= M00018_CR_BITMAP_RD_MSK
;
189 /* Last byte to read, no ACK */
191 cmd
|= M00018_CR_BITMAP_ACK_MSK
;
193 /* Execute command */
194 iowrite8(cmd
, ®s
->cr_sr
);
196 /* Wait for transfer to complete (TIP = 0) */
197 start_time
= jiffies
;
198 status
= ioread8(®s
->cr_sr
);
199 while (status
& M00018_SR_BITMAP_TIP_MSK
) {
200 if (time_after(jiffies
, start_time
+ adap
->timeout
))
203 status
= ioread8(®s
->cr_sr
);
206 /* Verify arbitration */
207 if (status
& M00018_SR_BITMAP_AL_MSK
) {
208 /* Arbitration lost! */
213 data
[i
] = ioread8(®s
->txr_rxr
);
218 /* Generate stop condition on i2c bus.
219 * The m00018 stop isn't doing the right thing (wrong timing).
220 * So instead send a start condition, 8 zeroes and a stop condition.
222 static int cobalt_stop(struct cobalt_i2c_regs __iomem
*regs
,
223 struct i2c_adapter
*adap
)
227 return cobalt_tx_bytes(regs
, adap
, true, true, &data
, 1);
230 static int cobalt_xfer(struct i2c_adapter
*adap
,
231 struct i2c_msg msgs
[], int num
)
233 struct cobalt_i2c_data
*data
= adap
->algo_data
;
234 struct cobalt_i2c_regs __iomem
*regs
= data
->regs
;
235 struct i2c_msg
*pmsg
;
236 unsigned short flags
;
240 for (i
= 0; i
< num
; i
++) {
241 int stop
= (i
== num
- 1);
246 if (!(pmsg
->flags
& I2C_M_NOSTART
)) {
247 u8 addr
= pmsg
->addr
<< 1;
249 if (flags
& I2C_M_RD
)
251 if (flags
& I2C_M_REV_DIR_ADDR
)
253 for (j
= 0; j
< adap
->retries
; j
++) {
254 ret
= cobalt_tx_bytes(regs
, adap
, true, false,
258 cobalt_stop(regs
, adap
);
264 if (pmsg
->flags
& I2C_M_RD
) {
265 /* read bytes into buffer */
266 ret
= cobalt_rx_bytes(regs
, adap
, false, stop
,
267 pmsg
->buf
, pmsg
->len
);
271 /* write bytes from buffer */
272 ret
= cobalt_tx_bytes(regs
, adap
, false, stop
,
273 pmsg
->buf
, pmsg
->len
);
282 cobalt_stop(regs
, adap
);
286 static u32
cobalt_func(struct i2c_adapter
*adap
)
288 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
291 /* template for i2c-bit-algo */
292 static const struct i2c_adapter cobalt_i2c_adap_template
= {
293 .name
= "cobalt i2c driver",
294 .algo
= NULL
, /* set by i2c-algo-bit */
295 .algo_data
= NULL
, /* filled from template */
296 .owner
= THIS_MODULE
,
299 static const struct i2c_algorithm cobalt_algo
= {
300 .master_xfer
= cobalt_xfer
,
301 .functionality
= cobalt_func
,
304 /* init + register i2c algo-bit adapter */
305 int cobalt_i2c_init(struct cobalt
*cobalt
)
310 unsigned long start_time
;
312 cobalt_dbg(1, "i2c init\n");
314 /* Define I2C clock prescaler */
315 prescale
= ((ALT_CPU_FREQ
) / (5 * I2C_FREQUENCY
)) - 1;
317 for (i
= 0; i
< COBALT_NUM_ADAPTERS
; i
++) {
318 struct cobalt_i2c_regs __iomem
*regs
=
319 cobalt_i2c_regs(cobalt
, i
);
320 struct i2c_adapter
*adap
= &cobalt
->i2c_adap
[i
];
323 iowrite8(M00018_CTR_BITMAP_EN_MSK
, ®s
->cr_sr
);
324 iowrite8(0, ®s
->ctr
);
325 iowrite8(0, ®s
->cr_sr
);
327 start_time
= jiffies
;
329 if (time_after(jiffies
, start_time
+ HZ
)) {
330 if (cobalt_ignore_err
) {
331 adap
->dev
.parent
= NULL
;
336 status
= ioread8(®s
->cr_sr
);
337 } while (status
& M00018_SR_BITMAP_TIP_MSK
);
340 iowrite8(0, ®s
->ctr
);
341 iowrite8(0, ®s
->cr_sr
);
343 /* Calculate i2c prescaler */
344 iowrite8(prescale
& 0xff, ®s
->prerlo
);
345 iowrite8((prescale
>> 8) & 0xff, ®s
->prerhi
);
346 /* Enable I2C, interrupts disabled */
347 iowrite8(M00018_CTR_BITMAP_EN_MSK
, ®s
->ctr
);
348 /* Setup algorithm for adapter */
349 cobalt
->i2c_data
[i
].cobalt
= cobalt
;
350 cobalt
->i2c_data
[i
].regs
= regs
;
351 *adap
= cobalt_i2c_adap_template
;
352 adap
->algo
= &cobalt_algo
;
353 adap
->algo_data
= &cobalt
->i2c_data
[i
];
355 sprintf(adap
->name
+ strlen(adap
->name
),
356 " #%d-%d", cobalt
->instance
, i
);
357 i2c_set_adapdata(adap
, &cobalt
->v4l2_dev
);
358 adap
->dev
.parent
= &cobalt
->pci_dev
->dev
;
359 err
= i2c_add_adapter(adap
);
361 if (cobalt_ignore_err
) {
362 adap
->dev
.parent
= NULL
;
366 i2c_del_adapter(&cobalt
->i2c_adap
[i
]);
369 cobalt_info("registered bus %s\n", adap
->name
);
374 void cobalt_i2c_exit(struct cobalt
*cobalt
)
378 cobalt_dbg(1, "i2c exit\n");
380 for (i
= 0; i
< COBALT_NUM_ADAPTERS
; i
++) {
381 cobalt_err("unregistered bus %s\n", cobalt
->i2c_adap
[i
].name
);
382 i2c_del_adapter(&cobalt
->i2c_adap
[i
]);