Skip to content

Commit 95edcf7

Browse files
ene-stevenkartben
authored andcommitted
driver: i2c: ene_kb1200 i2c slave address
Fix slave address, Notify transfer completion via semaphore Signed-off-by: Steven Chang <[email protected]>
1 parent 76c266c commit 95edcf7

File tree

2 files changed

+91
-49
lines changed

2 files changed

+91
-49
lines changed

drivers/i2c/i2c_ene_kb1200.c

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,20 @@
1212
#include <errno.h>
1313
#include <reg/fsmbm.h>
1414

15+
#include <zephyr/logging/log.h>
16+
LOG_MODULE_REGISTER(i2c_ene, CONFIG_I2C_LOG_LEVEL);
17+
18+
#include "i2c-priv.h"
19+
1520
struct i2c_kb1200_config {
1621
struct fsmbm_regs *fsmbm;
22+
uint32_t clock_freq;
1723
const struct pinctrl_dev_config *pcfg;
1824
};
1925

2026
struct i2c_kb1200_data {
21-
struct k_sem mutex;
27+
struct k_sem lock;
28+
struct k_sem wait;
2229
volatile uint8_t *msg_buf;
2330
volatile uint32_t msg_len;
2431
volatile uint8_t msg_flags;
@@ -39,6 +46,7 @@ static void i2c_kb1200_isr(const struct device *dev)
3946
uint32_t remain = data->msg_len - data->index;
4047
uint32_t send_bytes =
4148
remain > FSMBM_BUFFER_SIZE ? FSMBM_BUFFER_SIZE : remain;
49+
4250
memcpy((void *)&config->fsmbm->FSMBMDAT[0],
4351
(void *)&data->msg_buf[data->index], send_bytes);
4452
data->index += send_bytes;
@@ -52,7 +60,7 @@ static void i2c_kb1200_isr(const struct device *dev)
5260
} else if (config->fsmbm->FSMBMPF & FSMBM_COMPLETE_EVENT) {
5361
/* complete */
5462
if (((config->fsmbm->FSMBMSTS & FSMBM_STS_MASK) == FSMBM_SMBUS_BUSY) &&
55-
((config->fsmbm->FSMBMFRT & ___STOP) == ___NONE)) {
63+
((config->fsmbm->FSMBMFRT & FRT_STOP) == FRT_NONE)) {
5664
/* while packet finish without STOP, the error message is
5765
* FSMBM_SMBUS_BUSY
5866
*/
@@ -61,10 +69,12 @@ static void i2c_kb1200_isr(const struct device *dev)
6169
data->err_code = config->fsmbm->FSMBMSTS & FSMBM_STS_MASK;
6270
}
6371
data->state = STATE_COMPLETE;
72+
k_sem_give(&data->wait);
6473
config->fsmbm->FSMBMPF = FSMBM_COMPLETE_EVENT;
6574
} else {
6675
data->err_code = config->fsmbm->FSMBMSTS & FSMBM_STS_MASK;
6776
data->state = STATE_COMPLETE;
77+
k_sem_give(&data->wait);
6878
}
6979
} else if (data->state == STATE_RECEIVING) {
7080
uint32_t remain = data->msg_len - data->index;
@@ -89,7 +99,7 @@ static void i2c_kb1200_isr(const struct device *dev)
8999
} else if (config->fsmbm->FSMBMPF & FSMBM_COMPLETE_EVENT) {
90100
/* complete */
91101
if (((config->fsmbm->FSMBMSTS & FSMBM_STS_MASK) == FSMBM_SMBUS_BUSY) &&
92-
((config->fsmbm->FSMBMFRT & ___STOP) == ___NONE)) {
102+
((config->fsmbm->FSMBMFRT & FRT_STOP) == FRT_NONE)) {
93103
/* while packet finish without STOP, the error message is
94104
* FSMBM_SMBUS_BUSY
95105
*/
@@ -98,28 +108,33 @@ static void i2c_kb1200_isr(const struct device *dev)
98108
data->err_code = config->fsmbm->FSMBMSTS & FSMBM_STS_MASK;
99109
}
100110
data->state = STATE_COMPLETE;
111+
k_sem_give(&data->wait);
101112
config->fsmbm->FSMBMPF = FSMBM_COMPLETE_EVENT;
102113
} else {
103114
data->err_code = config->fsmbm->FSMBMSTS & FSMBM_STS_MASK;
104115
data->state = STATE_COMPLETE;
116+
k_sem_give(&data->wait);
105117
}
106118
} else if (data->state == STATE_COMPLETE) {
107119
config->fsmbm->FSMBMPF = (FSMBM_COMPLETE_EVENT | FSMBM_BLOCK_FINISH_EVENT);
120+
k_sem_give(&data->wait);
108121
}
109122
}
110123

111124
static int i2c_kb1200_poll_write(const struct device *dev, struct i2c_msg msg, uint16_t addr)
112125
{
113126
const struct i2c_kb1200_config *config = dev->config;
114127
struct i2c_kb1200_data *data = dev->data;
115-
uint8_t send_bytes;
128+
uint32_t send_bytes;
129+
int ret;
116130

131+
k_sem_reset(&data->wait);
117132
if (msg.flags & I2C_MSG_STOP) {
118133
/* No CMD, No CNT, No PEC, with STOP*/
119-
config->fsmbm->FSMBMFRT = ___STOP;
134+
config->fsmbm->FSMBMFRT = FRT_STOP;
120135
} else {
121136
/* No CMD, No CNT, No PEC, no STOP*/
122-
config->fsmbm->FSMBMFRT = ___NONE;
137+
config->fsmbm->FSMBMFRT = FRT_NONE;
123138
}
124139
data->msg_len = msg.len;
125140
data->msg_buf = msg.buf;
@@ -135,7 +150,7 @@ static int i2c_kb1200_poll_write(const struct device *dev, struct i2c_msg msg, u
135150
data->state = STATE_SENDING;
136151

137152
config->fsmbm->FSMBMCMD = 0;
138-
config->fsmbm->FSMBMADR = (addr & ~BIT(0)) | FSMBM_WRITE;
153+
config->fsmbm->FSMBMADR = (addr << 1) | FSMBM_WRITE;
139154
config->fsmbm->FSMBMPF = (FSMBM_COMPLETE_EVENT | FSMBM_BLOCK_FINISH_EVENT);
140155
/* If data over bufferSize increase 1 to force continue transmit */
141156
if (msg.len >= (FSMBM_BUFFER_SIZE + 1)) {
@@ -145,29 +160,38 @@ static int i2c_kb1200_poll_write(const struct device *dev, struct i2c_msg msg, u
145160
}
146161
config->fsmbm->FSMBMIE = (FSMBM_COMPLETE_EVENT | FSMBM_BLOCK_FINISH_EVENT);
147162
config->fsmbm->FSMBMPRTC_P = FLEXIBLE_PROTOCOL;
148-
while (data->state != STATE_COMPLETE) {
149-
;
163+
164+
/* Wait until ISR or timeout */
165+
ret = k_sem_take(&data->wait, K_MSEC(FSMBM_MAX_TIMEOUT));
166+
if (ret == -EAGAIN) {
167+
data->err_code |= FSMBM_SDA_TIMEOUT;
150168
}
151169
data->state = STATE_IDLE;
152-
if (data->err_code != 0) {
170+
if (data->err_code) {
153171
/* reset HW */
154172
config->fsmbm->FSMBMCFG |= FSMBM_HW_RESET;
155173
return data->err_code;
156174
}
175+
157176
return 0;
158177
}
159178

160179
static int i2c_kb1200_poll_read(const struct device *dev, struct i2c_msg msg, uint16_t addr)
161180
{
162181
const struct i2c_kb1200_config *config = dev->config;
163182
struct i2c_kb1200_data *data = dev->data;
183+
int ret;
164184

185+
k_sem_reset(&data->wait);
186+
if ((msg.flags & I2C_MSG_RESTART) && !(msg.flags & I2C_MSG_STOP)) {
187+
LOG_ERR("ENE i2c format not support.");
188+
}
165189
if (msg.flags & I2C_MSG_STOP) {
166190
/* No CMD, No CNT, No PEC, with STOP*/
167-
config->fsmbm->FSMBMFRT = ___STOP;
191+
config->fsmbm->FSMBMFRT = FRT_STOP;
168192
} else {
169193
/* No CMD, No CNT, No PEC, no STOP*/
170-
config->fsmbm->FSMBMFRT = ___NONE;
194+
config->fsmbm->FSMBMFRT = FRT_NONE;
171195
}
172196
data->msg_len = msg.len;
173197
data->msg_buf = msg.buf;
@@ -178,7 +202,7 @@ static int i2c_kb1200_poll_read(const struct device *dev, struct i2c_msg msg, ui
178202
data->state = STATE_RECEIVING;
179203

180204
config->fsmbm->FSMBMCMD = 0;
181-
config->fsmbm->FSMBMADR = (addr & ~BIT(0)) | FSMBM_READ;
205+
config->fsmbm->FSMBMADR = (addr << 1) | FSMBM_READ;
182206
config->fsmbm->FSMBMPF = (FSMBM_COMPLETE_EVENT | FSMBM_BLOCK_FINISH_EVENT);
183207
/* If data over bufferSize increase 1 to force continue receive */
184208
if (msg.len >= (FSMBM_BUFFER_SIZE + 1)) {
@@ -188,22 +212,28 @@ static int i2c_kb1200_poll_read(const struct device *dev, struct i2c_msg msg, ui
188212
}
189213
config->fsmbm->FSMBMIE = (FSMBM_COMPLETE_EVENT | FSMBM_BLOCK_FINISH_EVENT);
190214
config->fsmbm->FSMBMPRTC_P = FLEXIBLE_PROTOCOL;
191-
while (data->state != STATE_COMPLETE) {
192-
;
215+
216+
/* Wait until ISR or timeout */
217+
ret = k_sem_take(&data->wait, K_MSEC(FSMBM_MAX_TIMEOUT));
218+
if (ret == -EAGAIN) {
219+
data->err_code |= FSMBM_SDA_TIMEOUT;
193220
}
194221
data->state = STATE_IDLE;
195-
if (data->err_code != 0) {
222+
223+
if (data->err_code) {
196224
/* reset HW */
197225
config->fsmbm->FSMBMCFG |= FSMBM_HW_RESET;
198226
return data->err_code;
199227
}
228+
200229
return 0;
201230
}
202231

203232
/* I2C Master api functions */
204233
static int i2c_kb1200_configure(const struct device *dev, uint32_t dev_config)
205234
{
206235
const struct i2c_kb1200_config *config = dev->config;
236+
uint32_t speed;
207237

208238
if (!(dev_config & I2C_MODE_CONTROLLER)) {
209239
return -ENOTSUP;
@@ -213,7 +243,7 @@ static int i2c_kb1200_configure(const struct device *dev, uint32_t dev_config)
213243
return -ENOTSUP;
214244
}
215245

216-
uint32_t speed = I2C_SPEED_GET(dev_config);
246+
speed = I2C_SPEED_GET(dev_config);
217247

218248
switch (speed) {
219249
case I2C_SPEED_STANDARD:
@@ -242,7 +272,7 @@ static int i2c_kb1200_get_config(const struct device *dev, uint32_t *dev_config)
242272
const struct i2c_kb1200_config *config = dev->config;
243273

244274
if ((config->fsmbm->FSMBMCFG & FSMBM_FUNCTION_ENABLE) == 0x00) {
245-
printk("Cannot find i2c controller on 0x%p!\n", config->fsmbm);
275+
LOG_ERR("Cannot find i2c controller on 0x%p!", config->fsmbm);
246276
return -EIO;
247277
}
248278

@@ -251,6 +281,8 @@ static int i2c_kb1200_get_config(const struct device *dev, uint32_t *dev_config)
251281
*dev_config = I2C_MODE_CONTROLLER | I2C_SPEED_SET(I2C_SPEED_STANDARD);
252282
break;
253283
case FSMBM_CLK_400K:
284+
case FSMBM_CLK_500K:
285+
case FSMBM_CLK_666K:
254286
*dev_config = I2C_MODE_CONTROLLER | I2C_SPEED_SET(I2C_SPEED_FAST);
255287
break;
256288
case FSMBM_CLK_1M:
@@ -267,27 +299,27 @@ static int i2c_kb1200_transfer(const struct device *dev, struct i2c_msg *msgs, u
267299
uint16_t addr)
268300
{
269301
struct i2c_kb1200_data *data = dev->data;
270-
int ret;
302+
int ret = 0;
271303

272-
/* get the mutex */
273-
k_sem_take(&data->mutex, K_FOREVER);
304+
/* lock */
305+
k_sem_take(&data->lock, K_FOREVER);
274306
for (int i = 0U; i < num_msgs; i++) {
275307
if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
276308
ret = i2c_kb1200_poll_write(dev, msgs[i], addr);
277309
if (ret) {
278-
printk("%s Write error: 0x%X\n", dev->name, ret);
310+
ret = -EIO;
279311
break;
280312
}
281313
} else {
282314
ret = i2c_kb1200_poll_read(dev, msgs[i], addr);
283315
if (ret) {
284-
printk("%s Read error: 0x%X\n", dev->name, ret);
316+
ret = -EIO;
285317
break;
286318
}
287319
}
288320
}
289-
/* release the mutex */
290-
k_sem_give(&data->mutex);
321+
/* release the lock */
322+
k_sem_give(&data->lock);
291323

292324
return ret;
293325
}
@@ -332,14 +364,23 @@ static int i2c_kb1200_init(const struct device *dev)
332364
int ret;
333365
const struct i2c_kb1200_config *config = dev->config;
334366
struct i2c_kb1200_data *data = dev->data;
367+
uint32_t bitrate_cfg;
335368

336369
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
337370
if (ret != 0) {
338371
return ret;
339372
}
340373

341-
/* init mutex */
342-
k_sem_init(&data->mutex, 1, 1);
374+
bitrate_cfg = i2c_map_dt_bitrate(config->clock_freq);
375+
if (!bitrate_cfg) {
376+
return -EINVAL;
377+
}
378+
379+
i2c_kb1200_configure(dev, bitrate_cfg | I2C_MODE_CONTROLLER);
380+
381+
k_sem_init(&data->wait, 0, 1);
382+
/* init lock */
383+
k_sem_init(&data->lock, 1, 1);
343384
kb1200_fsmbm_irq_init();
344385

345386
return 0;
@@ -350,10 +391,11 @@ static int i2c_kb1200_init(const struct device *dev)
350391
static struct i2c_kb1200_data i2c_kb1200_data_##inst; \
351392
static const struct i2c_kb1200_config i2c_kb1200_config_##inst = { \
352393
.fsmbm = (struct fsmbm_regs *)DT_INST_REG_ADDR(inst), \
394+
.clock_freq = DT_INST_PROP(inst, clock_frequency), \
353395
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
354396
}; \
355397
I2C_DEVICE_DT_INST_DEFINE(inst, &i2c_kb1200_init, NULL, &i2c_kb1200_data_##inst, \
356-
&i2c_kb1200_config_##inst, PRE_KERNEL_1, \
357-
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &i2c_kb1200_api);
398+
&i2c_kb1200_config_##inst, PRE_KERNEL_1, \
399+
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &i2c_kb1200_api);
358400

359401
DT_INST_FOREACH_STATUS_OKAY(I2C_KB1200_DEVICE)

soc/ene/kb1200/reg/fsmbm.h

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,27 @@ struct fsmbm_regs {
5858
#define FSMBM_SMBUS_BUSY 0x1A
5959
#define FSMBM_STOP_FAIL 0x1E
6060
#define FSMBM_PEC_ERROR 0x1F
61+
#define FSMBM_SDA_TIMEOUT 0x80
62+
#define FSMBM_MAX_TIMEOUT 200 /* Unit: ms */
63+
6164
/* Packet Form */
62-
#define ___NONE 0x00
63-
#define ___STOP 0x01
64-
#define __PEC_ 0x02
65-
#define __PEC_STOP 0x03
66-
#define _CNT__ 0x04
67-
#define _CNT__STOP 0x05
68-
#define _CNT_PEC_ 0x06
69-
#define _CNT_PEC_STOP 0x07
70-
#define CMD___ 0x08
71-
#define CMD___STOP 0x09
72-
#define CMD__PEC_ 0x0A
73-
#define CMD__PEC_STOP 0x0B
74-
#define CMD_CNT__ 0x0C
75-
#define CMD_CNT__STOP 0x0D
76-
#define CMD_CNT_PEC_ 0x0E
77-
#define CMD_CNT_PEC_STOP 0x0F
65+
#define FRT_NONE 0x00
66+
#define FRT_STOP 0x01
67+
#define FRT_PEC 0x02
68+
#define FRT_CNT 0x04
69+
#define FRT_CMD 0x08
70+
#define FRT_PEC_STOP (FRT_PEC | FRT_STOP)
71+
#define FRT_CNT_STOP (FRT_CNT | FRT_STOP)
72+
#define FRT_CNT_PEC (FRT_CNT | FRT_PEC)
73+
#define FRT_CNT_PEC_STOP (FRT_CNT | FRT_PEC | FRT_STOP)
74+
#define FRT_CMD_STOP (FRT_CMD | FRT_STOP)
75+
#define FRT_CMD_PEC (FRT_CMD | FRT_PEC)
76+
#define FRT_CMD_PEC_STOP (FRT_CMD | FRT_PEC | FRT_STOP)
77+
#define FRT_CMD_CNT (FRT_CMD | FRT_CNT)
78+
#define FRT_CMD_CNT_STOP (FRT_CMD | FRT_CNT | FRT_STOP)
79+
#define FRT_CMD_CNT_PEC (FRT_CMD | FRT_CNT | FRT_PEC)
80+
#define FRT_CMD_CNT_PEC_STOP (FRT_CMD | FRT_CNT | FRT_PEC | FRT_STOP)
7881

79-
#define FLEXIBLE_CMD 0x08
80-
#define FLEXIBLE_CNT 0x04
81-
#define FLEXIBLE_PEC 0x02
82-
#define FLEXIBLE_STOP 0x01
8382
/* HW */
8483
#define FSMBM_BUFFER_SIZE 0x20
8584
#define FSMBM_MAXCNT 0xFF
@@ -109,6 +108,7 @@ struct fsmbm_regs {
109108
#define FSMBM_CLK_10K 0x6363
110109
/* Other(non 50% Duty Cycle) */
111110
#define FSMBM_CLK_400K 0x0102
111+
#define FSMBM_CLK_666K 0x0001
112112

113113
#define FSMBM_COMPLETE_EVENT 0x01
114114
#define FSMBM_HOST_NOTIFY_EVENT 0x02

0 commit comments

Comments
 (0)