1/* 2 * I2C bus driver for Conexant Digicolor SoCs 3 * 4 * Author: Baruch Siach <baruch@tkos.co.il> 5 * 6 * Copyright (C) 2015 Paradox Innovation Ltd. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13#include <linux/clk.h> 14#include <linux/completion.h> 15#include <linux/delay.h> 16#include <linux/i2c.h> 17#include <linux/interrupt.h> 18#include <linux/io.h> 19#include <linux/kernel.h> 20#include <linux/module.h> 21#include <linux/of.h> 22#include <linux/platform_device.h> 23 24#define DEFAULT_FREQ 100000 25#define TIMEOUT_MS 100 26 27#define II_CONTROL 0x0 28#define II_CONTROL_LOCAL_RESET BIT(0) 29 30#define II_CLOCKTIME 0x1 31 32#define II_COMMAND 0x2 33#define II_CMD_START 1 34#define II_CMD_RESTART 2 35#define II_CMD_SEND_ACK 3 36#define II_CMD_GET_ACK 6 37#define II_CMD_GET_NOACK 7 38#define II_CMD_STOP 10 39#define II_COMMAND_GO BIT(7) 40#define II_COMMAND_COMPLETION_STATUS(r) (((r) >> 5) & 3) 41#define II_CMD_STATUS_NORMAL 0 42#define II_CMD_STATUS_ACK_GOOD 1 43#define II_CMD_STATUS_ACK_BAD 2 44#define II_CMD_STATUS_ABORT 3 45 46#define II_DATA 0x3 47#define II_INTFLAG_CLEAR 0x8 48#define II_INTENABLE 0xa 49 50struct dc_i2c { 51 struct i2c_adapter adap; 52 struct device *dev; 53 void __iomem *regs; 54 struct clk *clk; 55 unsigned int frequency; 56 57 struct i2c_msg *msg; 58 unsigned int msgbuf_ptr; 59 int last; 60 spinlock_t lock; 61 struct completion done; 62 int state; 63 int error; 64}; 65 66enum { 67 STATE_IDLE, 68 STATE_START, 69 STATE_ADDR, 70 STATE_WRITE, 71 STATE_READ, 72 STATE_STOP, 73}; 74 75static void dc_i2c_cmd(struct dc_i2c *i2c, u8 cmd) 76{ 77 writeb_relaxed(cmd | II_COMMAND_GO, i2c->regs + II_COMMAND); 78} 79 80static u8 dc_i2c_addr_cmd(struct i2c_msg *msg) 81{ 82 u8 addr = (msg->addr & 0x7f) << 1; 83 84 if (msg->flags & I2C_M_RD) 85 addr |= 1; 86 87 return addr; 88} 89 90static void dc_i2c_data(struct dc_i2c *i2c, u8 data) 91{ 92 writeb_relaxed(data, i2c->regs + II_DATA); 93} 94 95static void dc_i2c_write_byte(struct dc_i2c *i2c, u8 byte) 96{ 97 dc_i2c_data(i2c, byte); 98 dc_i2c_cmd(i2c, II_CMD_SEND_ACK); 99} 100 101static void dc_i2c_write_buf(struct dc_i2c *i2c) 102{ 103 dc_i2c_write_byte(i2c, i2c->msg->buf[i2c->msgbuf_ptr++]); 104} 105 106static void dc_i2c_next_read(struct dc_i2c *i2c) 107{ 108 bool last = (i2c->msgbuf_ptr + 1 == i2c->msg->len); 109 110 dc_i2c_cmd(i2c, last ? II_CMD_GET_NOACK : II_CMD_GET_ACK); 111} 112 113static void dc_i2c_stop(struct dc_i2c *i2c) 114{ 115 i2c->state = STATE_STOP; 116 if (i2c->last) 117 dc_i2c_cmd(i2c, II_CMD_STOP); 118 else 119 complete(&i2c->done); 120} 121 122static u8 dc_i2c_read_byte(struct dc_i2c *i2c) 123{ 124 return readb_relaxed(i2c->regs + II_DATA); 125} 126 127static void dc_i2c_read_buf(struct dc_i2c *i2c) 128{ 129 i2c->msg->buf[i2c->msgbuf_ptr++] = dc_i2c_read_byte(i2c); 130 dc_i2c_next_read(i2c); 131} 132 133static void dc_i2c_set_irq(struct dc_i2c *i2c, int enable) 134{ 135 if (enable) 136 writeb_relaxed(1, i2c->regs + II_INTFLAG_CLEAR); 137 writeb_relaxed(!!enable, i2c->regs + II_INTENABLE); 138} 139 140static int dc_i2c_cmd_status(struct dc_i2c *i2c) 141{ 142 u8 cmd = readb_relaxed(i2c->regs + II_COMMAND); 143 144 return II_COMMAND_COMPLETION_STATUS(cmd); 145} 146 147static void dc_i2c_start_msg(struct dc_i2c *i2c, int first) 148{ 149 struct i2c_msg *msg = i2c->msg; 150 151 if (!(msg->flags & I2C_M_NOSTART)) { 152 i2c->state = STATE_START; 153 dc_i2c_cmd(i2c, first ? II_CMD_START : II_CMD_RESTART); 154 } else if (msg->flags & I2C_M_RD) { 155 i2c->state = STATE_READ; 156 dc_i2c_next_read(i2c); 157 } else { 158 i2c->state = STATE_WRITE; 159 dc_i2c_write_buf(i2c); 160 } 161} 162 163static irqreturn_t dc_i2c_irq(int irq, void *dev_id) 164{ 165 struct dc_i2c *i2c = dev_id; 166 int cmd_status = dc_i2c_cmd_status(i2c); 167 unsigned long flags; 168 u8 addr_cmd; 169 170 writeb_relaxed(1, i2c->regs + II_INTFLAG_CLEAR); 171 172 spin_lock_irqsave(&i2c->lock, flags); 173 174 if (cmd_status == II_CMD_STATUS_ACK_BAD 175 || cmd_status == II_CMD_STATUS_ABORT) { 176 i2c->error = -EIO; 177 complete(&i2c->done); 178 goto out; 179 } 180 181 switch (i2c->state) { 182 case STATE_START: 183 addr_cmd = dc_i2c_addr_cmd(i2c->msg); 184 dc_i2c_write_byte(i2c, addr_cmd); 185 i2c->state = STATE_ADDR; 186 break; 187 case STATE_ADDR: 188 if (i2c->msg->flags & I2C_M_RD) { 189 dc_i2c_next_read(i2c); 190 i2c->state = STATE_READ; 191 break; 192 } 193 i2c->state = STATE_WRITE; 194 /* fall through */ 195 case STATE_WRITE: 196 if (i2c->msgbuf_ptr < i2c->msg->len) 197 dc_i2c_write_buf(i2c); 198 else 199 dc_i2c_stop(i2c); 200 break; 201 case STATE_READ: 202 if (i2c->msgbuf_ptr < i2c->msg->len) 203 dc_i2c_read_buf(i2c); 204 else 205 dc_i2c_stop(i2c); 206 break; 207 case STATE_STOP: 208 i2c->state = STATE_IDLE; 209 complete(&i2c->done); 210 break; 211 } 212 213out: 214 spin_unlock_irqrestore(&i2c->lock, flags); 215 return IRQ_HANDLED; 216} 217 218static int dc_i2c_xfer_msg(struct dc_i2c *i2c, struct i2c_msg *msg, int first, 219 int last) 220{ 221 unsigned long timeout = msecs_to_jiffies(TIMEOUT_MS); 222 unsigned long flags; 223 224 spin_lock_irqsave(&i2c->lock, flags); 225 i2c->msg = msg; 226 i2c->msgbuf_ptr = 0; 227 i2c->last = last; 228 i2c->error = 0; 229 230 reinit_completion(&i2c->done); 231 dc_i2c_set_irq(i2c, 1); 232 dc_i2c_start_msg(i2c, first); 233 spin_unlock_irqrestore(&i2c->lock, flags); 234 235 timeout = wait_for_completion_timeout(&i2c->done, timeout); 236 dc_i2c_set_irq(i2c, 0); 237 if (timeout == 0) { 238 i2c->state = STATE_IDLE; 239 return -ETIMEDOUT; 240 } 241 242 if (i2c->error) 243 return i2c->error; 244 245 return 0; 246} 247 248static int dc_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 249{ 250 struct dc_i2c *i2c = adap->algo_data; 251 int i, ret; 252 253 for (i = 0; i < num; i++) { 254 ret = dc_i2c_xfer_msg(i2c, &msgs[i], i == 0, i == num - 1); 255 if (ret) 256 return ret; 257 } 258 259 return num; 260} 261 262static int dc_i2c_init_hw(struct dc_i2c *i2c) 263{ 264 unsigned long clk_rate = clk_get_rate(i2c->clk); 265 unsigned int clocktime; 266 267 writeb_relaxed(II_CONTROL_LOCAL_RESET, i2c->regs + II_CONTROL); 268 udelay(100); 269 writeb_relaxed(0, i2c->regs + II_CONTROL); 270 udelay(100); 271 272 clocktime = DIV_ROUND_UP(clk_rate, 64 * i2c->frequency); 273 if (clocktime < 1 || clocktime > 0xff) { 274 dev_err(i2c->dev, "can't set bus speed of %u Hz\n", 275 i2c->frequency); 276 return -EINVAL; 277 } 278 writeb_relaxed(clocktime - 1, i2c->regs + II_CLOCKTIME); 279 280 return 0; 281} 282 283static u32 dc_i2c_func(struct i2c_adapter *adap) 284{ 285 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_NOSTART; 286} 287 288static const struct i2c_algorithm dc_i2c_algorithm = { 289 .master_xfer = dc_i2c_xfer, 290 .functionality = dc_i2c_func, 291}; 292 293static int dc_i2c_probe(struct platform_device *pdev) 294{ 295 struct device_node *np = pdev->dev.of_node; 296 struct dc_i2c *i2c; 297 struct resource *r; 298 int ret = 0, irq; 299 300 i2c = devm_kzalloc(&pdev->dev, sizeof(struct dc_i2c), GFP_KERNEL); 301 if (!i2c) 302 return -ENOMEM; 303 304 if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", 305 &i2c->frequency)) 306 i2c->frequency = DEFAULT_FREQ; 307 308 i2c->dev = &pdev->dev; 309 platform_set_drvdata(pdev, i2c); 310 311 spin_lock_init(&i2c->lock); 312 init_completion(&i2c->done); 313 314 i2c->clk = devm_clk_get(&pdev->dev, NULL); 315 if (IS_ERR(i2c->clk)) 316 return PTR_ERR(i2c->clk); 317 318 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 319 i2c->regs = devm_ioremap_resource(&pdev->dev, r); 320 if (IS_ERR(i2c->regs)) 321 return PTR_ERR(i2c->regs); 322 323 irq = platform_get_irq(pdev, 0); 324 if (irq < 0) 325 return irq; 326 327 ret = devm_request_irq(&pdev->dev, irq, dc_i2c_irq, 0, 328 dev_name(&pdev->dev), i2c); 329 if (ret < 0) 330 return ret; 331 332 strlcpy(i2c->adap.name, "Conexant Digicolor I2C adapter", 333 sizeof(i2c->adap.name)); 334 i2c->adap.owner = THIS_MODULE; 335 i2c->adap.algo = &dc_i2c_algorithm; 336 i2c->adap.dev.parent = &pdev->dev; 337 i2c->adap.dev.of_node = np; 338 i2c->adap.algo_data = i2c; 339 340 ret = dc_i2c_init_hw(i2c); 341 if (ret) 342 return ret; 343 344 ret = clk_prepare_enable(i2c->clk); 345 if (ret < 0) 346 return ret; 347 348 ret = i2c_add_adapter(&i2c->adap); 349 if (ret < 0) { 350 clk_unprepare(i2c->clk); 351 return ret; 352 } 353 354 return 0; 355} 356 357static int dc_i2c_remove(struct platform_device *pdev) 358{ 359 struct dc_i2c *i2c = platform_get_drvdata(pdev); 360 361 i2c_del_adapter(&i2c->adap); 362 clk_disable_unprepare(i2c->clk); 363 364 return 0; 365} 366 367static const struct of_device_id dc_i2c_match[] = { 368 { .compatible = "cnxt,cx92755-i2c" }, 369 { }, 370}; 371 372static struct platform_driver dc_i2c_driver = { 373 .probe = dc_i2c_probe, 374 .remove = dc_i2c_remove, 375 .driver = { 376 .name = "digicolor-i2c", 377 .of_match_table = dc_i2c_match, 378 }, 379}; 380module_platform_driver(dc_i2c_driver); 381 382MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 383MODULE_DESCRIPTION("Conexant Digicolor I2C master driver"); 384MODULE_LICENSE("GPL v2"); 385