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