1 /* 2 * Atmel I2C driver. 3 * 4 * (C) Copyright 2016 Songjun Wu <songjun.wu@atmel.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <asm/io.h> 10 #include <common.h> 11 #include <clk.h> 12 #include <dm.h> 13 #include <errno.h> 14 #include <fdtdec.h> 15 #include <i2c.h> 16 #include <linux/bitops.h> 17 #include <mach/clk.h> 18 19 #include "at91_i2c.h" 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 #define I2C_TIMEOUT_MS 100 24 25 static int at91_wait_for_xfer(struct at91_i2c_bus *bus, u32 status) 26 { 27 struct at91_i2c_regs *reg = bus->regs; 28 ulong start_time = get_timer(0); 29 u32 sr; 30 31 bus->status = 0; 32 33 do { 34 sr = readl(®->sr); 35 bus->status |= sr; 36 37 if (sr & TWI_SR_NACK) 38 return -EREMOTEIO; 39 else if (sr & status) 40 return 0; 41 } while (get_timer(start_time) < I2C_TIMEOUT_MS); 42 43 return -ETIMEDOUT; 44 } 45 46 static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) 47 { 48 struct at91_i2c_regs *reg = bus->regs; 49 bool is_read = msg->flags & I2C_M_RD; 50 u32 i; 51 int ret = 0; 52 53 readl(®->sr); 54 if (is_read) { 55 writel(TWI_CR_START, ®->cr); 56 57 for (i = 0; !ret && i < (msg->len - 1); i++) { 58 ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY); 59 msg->buf[i] = readl(®->rhr); 60 } 61 62 if (ret) 63 goto error; 64 65 writel(TWI_CR_STOP, ®->cr); 66 67 ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY); 68 if (ret) 69 goto error; 70 71 msg->buf[i] = readl(®->rhr); 72 73 } else { 74 writel(msg->buf[0], ®->thr); 75 for (i = 1; !ret && (i < msg->len); i++) { 76 writel(msg->buf[i], ®->thr); 77 ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); 78 } 79 80 if (ret) 81 goto error; 82 83 writel(TWI_CR_STOP, ®->cr); 84 } 85 86 if (!ret) 87 ret = at91_wait_for_xfer(bus, TWI_SR_TXCOMP); 88 89 if (ret) 90 goto error; 91 92 if (bus->status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_LOCK)) { 93 ret = -EIO; 94 goto error; 95 } 96 97 return 0; 98 99 error: 100 if (bus->status & TWI_SR_LOCK) 101 writel(TWI_CR_LOCKCLR, ®->cr); 102 103 return ret; 104 } 105 106 static int at91_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) 107 { 108 struct at91_i2c_bus *bus = dev_get_priv(dev); 109 struct at91_i2c_regs *reg = bus->regs; 110 struct i2c_msg *m_start = msg; 111 bool is_read; 112 u32 int_addr_flag = 0; 113 int ret = 0; 114 115 if (nmsgs == 2) { 116 int internal_address = 0; 117 int i; 118 119 /* 1st msg is put into the internal address, start with 2nd */ 120 m_start = &msg[1]; 121 122 /* the max length of internal address is 3 bytes */ 123 if (msg->len > 3) 124 return -EFAULT; 125 126 for (i = 0; i < msg->len; ++i) { 127 const unsigned addr = msg->buf[msg->len - 1 - i]; 128 129 internal_address |= addr << (8 * i); 130 int_addr_flag += TWI_MMR_IADRSZ_1; 131 } 132 133 writel(internal_address, ®->iadr); 134 } 135 136 is_read = m_start->flags & I2C_M_RD; 137 138 writel((m_start->addr << 16) | int_addr_flag | 139 (is_read ? TWI_MMR_MREAD : 0), ®->mmr); 140 141 ret = at91_i2c_xfer_msg(bus, m_start); 142 143 return ret; 144 } 145 146 /* 147 * Calculate symmetric clock as stated in datasheet: 148 * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset)) 149 */ 150 static void at91_calc_i2c_clock(struct udevice *dev, int i2c_clk) 151 { 152 struct at91_i2c_bus *bus = dev_get_priv(dev); 153 const struct at91_i2c_pdata *pdata = bus->pdata; 154 int offset = pdata->clk_offset; 155 int max_ckdiv = pdata->clk_max_div; 156 int ckdiv, cdiv, div; 157 unsigned long src_rate; 158 159 src_rate = bus->bus_clk_rate; 160 161 div = max(0, (int)DIV_ROUND_UP(src_rate, 2 * i2c_clk) - offset); 162 ckdiv = fls(div >> 8); 163 cdiv = div >> ckdiv; 164 165 if (ckdiv > max_ckdiv) { 166 ckdiv = max_ckdiv; 167 cdiv = 255; 168 } 169 170 bus->speed = DIV_ROUND_UP(src_rate, 171 (cdiv * (1 << ckdiv) + offset) * 2); 172 173 bus->cwgr_val = (ckdiv << 16) | (cdiv << 8) | cdiv; 174 } 175 176 static int at91_i2c_enable_clk(struct udevice *dev) 177 { 178 struct at91_i2c_bus *bus = dev_get_priv(dev); 179 struct clk clk; 180 ulong clk_rate; 181 int ret; 182 183 ret = clk_get_by_index(dev, 0, &clk); 184 if (ret) 185 return -EINVAL; 186 187 ret = clk_enable(&clk); 188 if (ret) 189 return ret; 190 191 clk_rate = clk_get_rate(&clk); 192 if (!clk_rate) 193 return -EINVAL; 194 195 bus->bus_clk_rate = clk_rate; 196 197 clk_free(&clk); 198 199 return 0; 200 } 201 202 static int at91_i2c_probe_chip(struct udevice *dev, uint chip, uint chip_flags) 203 { 204 struct at91_i2c_bus *bus = dev_get_priv(dev); 205 struct at91_i2c_regs *reg = bus->regs; 206 int ret; 207 208 ret = at91_i2c_enable_clk(dev); 209 if (ret) 210 return ret; 211 212 writel(TWI_CR_SWRST, ®->cr); 213 214 at91_calc_i2c_clock(dev, bus->clock_frequency); 215 216 writel(bus->cwgr_val, ®->cwgr); 217 writel(TWI_CR_MSEN, ®->cr); 218 writel(TWI_CR_SVDIS, ®->cr); 219 220 return 0; 221 } 222 223 static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) 224 { 225 struct at91_i2c_bus *bus = dev_get_priv(dev); 226 227 at91_calc_i2c_clock(dev, speed); 228 229 writel(bus->cwgr_val, &bus->regs->cwgr); 230 231 return 0; 232 } 233 234 int at91_i2c_get_bus_speed(struct udevice *dev) 235 { 236 struct at91_i2c_bus *bus = dev_get_priv(dev); 237 238 return bus->speed; 239 } 240 241 static int at91_i2c_ofdata_to_platdata(struct udevice *dev) 242 { 243 const void *blob = gd->fdt_blob; 244 struct at91_i2c_bus *bus = dev_get_priv(dev); 245 int node = dev_of_offset(dev); 246 247 bus->regs = (struct at91_i2c_regs *)devfdt_get_addr(dev); 248 bus->pdata = (struct at91_i2c_pdata *)dev_get_driver_data(dev); 249 bus->clock_frequency = fdtdec_get_int(blob, node, 250 "clock-frequency", 100000); 251 252 return 0; 253 } 254 255 static const struct dm_i2c_ops at91_i2c_ops = { 256 .xfer = at91_i2c_xfer, 257 .probe_chip = at91_i2c_probe_chip, 258 .set_bus_speed = at91_i2c_set_bus_speed, 259 .get_bus_speed = at91_i2c_get_bus_speed, 260 }; 261 262 static int at91_i2c_probe(struct udevice *dev) 263 { 264 struct at91_i2c_bus *bus = dev_get_priv(dev); 265 struct at91_i2c_regs *reg = bus->regs; 266 int ret; 267 268 ret = at91_i2c_enable_clk(dev); 269 if (ret) 270 return ret; 271 272 writel(TWI_CR_SWRST, ®->cr); 273 274 at91_calc_i2c_clock(dev, bus->clock_frequency); 275 276 writel(bus->cwgr_val, ®->cwgr); 277 writel(TWI_CR_MSEN, ®->cr); 278 writel(TWI_CR_SVDIS, ®->cr); 279 280 return 0; 281 } 282 283 static const struct at91_i2c_pdata at91rm9200_config = { 284 .clk_max_div = 5, 285 .clk_offset = 3, 286 }; 287 288 static const struct at91_i2c_pdata at91sam9261_config = { 289 .clk_max_div = 5, 290 .clk_offset = 4, 291 }; 292 293 static const struct at91_i2c_pdata at91sam9260_config = { 294 .clk_max_div = 7, 295 .clk_offset = 4, 296 }; 297 298 static const struct at91_i2c_pdata at91sam9g20_config = { 299 .clk_max_div = 7, 300 .clk_offset = 4, 301 }; 302 303 static const struct at91_i2c_pdata at91sam9g10_config = { 304 .clk_max_div = 7, 305 .clk_offset = 4, 306 }; 307 308 static const struct at91_i2c_pdata at91sam9x5_config = { 309 .clk_max_div = 7, 310 .clk_offset = 4, 311 }; 312 313 static const struct at91_i2c_pdata sama5d4_config = { 314 .clk_max_div = 7, 315 .clk_offset = 4, 316 }; 317 318 static const struct at91_i2c_pdata sama5d2_config = { 319 .clk_max_div = 7, 320 .clk_offset = 3, 321 }; 322 323 static const struct udevice_id at91_i2c_ids[] = { 324 { .compatible = "atmel,at91rm9200-i2c", .data = (long)&at91rm9200_config }, 325 { .compatible = "atmel,at91sam9260-i2c", .data = (long)&at91sam9260_config }, 326 { .compatible = "atmel,at91sam9261-i2c", .data = (long)&at91sam9261_config }, 327 { .compatible = "atmel,at91sam9g20-i2c", .data = (long)&at91sam9g20_config }, 328 { .compatible = "atmel,at91sam9g10-i2c", .data = (long)&at91sam9g10_config }, 329 { .compatible = "atmel,at91sam9x5-i2c", .data = (long)&at91sam9x5_config }, 330 { .compatible = "atmel,sama5d4-i2c", .data = (long)&sama5d4_config }, 331 { .compatible = "atmel,sama5d2-i2c", .data = (long)&sama5d2_config }, 332 { } 333 }; 334 335 U_BOOT_DRIVER(i2c_at91) = { 336 .name = "i2c_at91", 337 .id = UCLASS_I2C, 338 .of_match = at91_i2c_ids, 339 .probe = at91_i2c_probe, 340 .ofdata_to_platdata = at91_i2c_ofdata_to_platdata, 341 .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), 342 .priv_auto_alloc_size = sizeof(struct at91_i2c_bus), 343 .ops = &at91_i2c_ops, 344 }; 345