Commit 3dab3e0e6785efad54e5919d3b30fb99a6e6402e

Authored by Nobuhiro Iwamatsu
Committed by Wolfgang Denk
1 parent f52138ae87
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

i2c: sh: Add support I2C for Renesas SH

This supports I2C of Renesas SH.
I tested on SH7724.

Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
CC: Heiko Schocher <hs@denx.de>

Showing 2 changed files with 293 additions and 0 deletions Side-by-side Diff

drivers/i2c/Makefile
... ... @@ -43,6 +43,7 @@
43 43 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
44 44 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
45 45 COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
  46 +COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
46 47  
47 48 COBJS := $(COBJS-y)
48 49 SRCS := $(COBJS:.o=.c)
drivers/i2c/sh_i2c.c
  1 +/*
  2 + * Copyright (C) 2011 Renesas Solutions Corp.
  3 + * Copyright (C) 2011 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
  4 + *
  5 + * This program is free software; you can redistribute it and/or
  6 + * modify it under the terms of the GNU General Public License as
  7 + * published by the Free Software Foundation; either version 2 of
  8 + * the License, or (at your option) any later version.
  9 + *
  10 + * This program is distributed in the hope that it will be useful,
  11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 + * GNU General Public License for more details.
  14 + *
  15 + * You should have received a copy of the GNU General Public License
  16 + * along with this program; if not, write to the Free Software
  17 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18 + * MA 02111-1307 USA
  19 + */
  20 +
  21 +#include <common.h>
  22 +#include <asm/io.h>
  23 +
  24 +/* Every register is 32bit aligned, but only 8bits in size */
  25 +#define ureg(name) u8 name; u8 __pad_##name##0; u16 __pad_##name##1;
  26 +struct sh_i2c {
  27 + ureg(icdr);
  28 + ureg(iccr);
  29 + ureg(icsr);
  30 + ureg(icic);
  31 + ureg(iccl);
  32 + ureg(icch);
  33 +};
  34 +#undef ureg
  35 +
  36 +static struct sh_i2c *base;
  37 +
  38 +/* ICCR */
  39 +#define SH_I2C_ICCR_ICE (1 << 7)
  40 +#define SH_I2C_ICCR_RACK (1 << 6)
  41 +#define SH_I2C_ICCR_RTS (1 << 4)
  42 +#define SH_I2C_ICCR_BUSY (1 << 2)
  43 +#define SH_I2C_ICCR_SCP (1 << 0)
  44 +
  45 +/* ICSR / ICIC */
  46 +#define SH_IC_BUSY (1 << 3)
  47 +#define SH_IC_TACK (1 << 2)
  48 +#define SH_IC_WAIT (1 << 1)
  49 +#define SH_IC_DTE (1 << 0)
  50 +
  51 +static u8 iccl, icch;
  52 +
  53 +#define IRQ_WAIT 1000
  54 +
  55 +static void irq_wait(struct sh_i2c *base)
  56 +{
  57 + int i;
  58 + u8 status;
  59 +
  60 + for (i = 0 ; i < IRQ_WAIT ; i++) {
  61 + status = readb(&base->icsr);
  62 + if (SH_IC_WAIT & status)
  63 + break;
  64 +
  65 + udelay(10);
  66 + }
  67 +
  68 + writeb(status & ~SH_IC_WAIT, &base->icsr);
  69 +}
  70 +
  71 +static void irq_dte(struct sh_i2c *base)
  72 +{
  73 + int i;
  74 +
  75 + for (i = 0 ; i < IRQ_WAIT ; i++) {
  76 + if (SH_IC_DTE & readb(&base->icsr))
  77 + break;
  78 + udelay(10);
  79 + }
  80 +}
  81 +
  82 +static void irq_busy(struct sh_i2c *base)
  83 +{
  84 + int i;
  85 +
  86 + for (i = 0 ; i < IRQ_WAIT ; i++) {
  87 + if (!(SH_IC_BUSY & readb(&base->icsr)))
  88 + break;
  89 + udelay(10);
  90 + }
  91 +}
  92 +
  93 +static void i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg, int stop)
  94 +{
  95 + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr);
  96 + writeb(readb(&base->iccr) | SH_I2C_ICCR_ICE, &base->iccr);
  97 +
  98 + writeb(iccl, &base->iccl);
  99 + writeb(icch, &base->icch);
  100 + writeb(0, &base->icic);
  101 +
  102 + writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr);
  103 + irq_dte(base);
  104 +
  105 + writeb(id << 1, &base->icdr);
  106 + irq_dte(base);
  107 +
  108 + writeb(reg, &base->icdr);
  109 + if (stop)
  110 + writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS), &base->iccr);
  111 +
  112 + irq_dte(base);
  113 +}
  114 +
  115 +static void i2c_finish(struct sh_i2c *base)
  116 +{
  117 + writeb(0, &base->icsr);
  118 + writeb(readb(&base->iccr) & ~SH_I2C_ICCR_ICE, &base->iccr);
  119 +}
  120 +
  121 +static void i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 val)
  122 +{
  123 + i2c_set_addr(base, id, reg, 0);
  124 + udelay(10);
  125 +
  126 + writeb(val, &base->icdr);
  127 + irq_dte(base);
  128 +
  129 + writeb((SH_I2C_ICCR_ICE | SH_I2C_ICCR_RTS), &base->iccr);
  130 + irq_dte(base);
  131 + irq_busy(base);
  132 +
  133 + i2c_finish(base);
  134 +}
  135 +
  136 +static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg)
  137 +{
  138 + u8 ret;
  139 +
  140 + i2c_set_addr(base, id, reg, 1);
  141 + udelay(100);
  142 +
  143 + writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RTS|SH_I2C_ICCR_BUSY), &base->iccr);
  144 + irq_dte(base);
  145 +
  146 + writeb(id << 1 | 0x01, &base->icdr);
  147 + irq_dte(base);
  148 +
  149 + writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_SCP), &base->iccr);
  150 + irq_dte(base);
  151 +
  152 + ret = readb(&base->icdr);
  153 +
  154 + writeb((SH_I2C_ICCR_ICE|SH_I2C_ICCR_RACK), &base->iccr);
  155 + readb(&base->icdr); /* Dummy read */
  156 + irq_busy(base);
  157 +
  158 + i2c_finish(base);
  159 +
  160 + return ret;
  161 +}
  162 +
  163 +#ifdef CONFIG_I2C_MULTI_BUS
  164 +static unsigned int current_bus;
  165 +
  166 +/**
  167 + * i2c_set_bus_num - change active I2C bus
  168 + * @bus: bus index, zero based
  169 + * @returns: 0 on success, non-0 on failure
  170 + */
  171 +int i2c_set_bus_num(unsigned int bus)
  172 +{
  173 + if ((bus < 0) || (bus >= CONFIG_SYS_MAX_I2C_BUS)) {
  174 + printf("Bad bus: %d\n", bus);
  175 + return -1;
  176 + }
  177 +
  178 + switch (bus) {
  179 + case 0:
  180 + base = (void *)CONFIG_SH_I2C_BASE0;
  181 + break;
  182 + case 1:
  183 + base = (void *)CONFIG_SH_I2C_BASE1;
  184 + break;
  185 + default:
  186 + return -1;
  187 + }
  188 + current_bus = bus;
  189 +
  190 + return 0;
  191 +}
  192 +
  193 +/**
  194 + * i2c_get_bus_num - returns index of active I2C bus
  195 + */
  196 +unsigned int i2c_get_bus_num(void)
  197 +{
  198 + return current_bus;
  199 +}
  200 +#endif
  201 +
  202 +#define SH_I2C_ICCL_CALC(clk, date, t_low, t_high) \
  203 + ((clk / rate) * (t_low / t_low + t_high))
  204 +#define SH_I2C_ICCH_CALC(clk, date, t_low, t_high) \
  205 + ((clk / rate) * (t_high / t_low + t_high))
  206 +
  207 +void i2c_init(int speed, int slaveaddr)
  208 +{
  209 + int num, denom, tmp;
  210 +
  211 +#ifdef CONFIG_I2C_MULTI_BUS
  212 + current_bus = 0;
  213 +#endif
  214 + base = (struct sh_i2c *)CONFIG_SH_I2C_BASE0;
  215 +
  216 + /*
  217 + * Calculate the value for iccl. From the data sheet:
  218 + * iccl = (p-clock / transfer-rate) * (L / (L + H))
  219 + * where L and H are the SCL low and high ratio.
  220 + */
  221 + num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_LOW;
  222 + denom = speed * (CONFIG_SH_I2C_DATA_HIGH + CONFIG_SH_I2C_DATA_LOW);
  223 + tmp = num * 10 / denom;
  224 + if (tmp % 10 >= 5)
  225 + iccl = (u8)((num/denom) + 1);
  226 + else
  227 + iccl = (u8)(num/denom);
  228 +
  229 + /* Calculate the value for icch. From the data sheet:
  230 + icch = (p clock / transfer rate) * (H / (L + H)) */
  231 + num = CONFIG_SH_I2C_CLOCK * CONFIG_SH_I2C_DATA_HIGH;
  232 + tmp = num * 10 / denom;
  233 + if (tmp % 10 >= 5)
  234 + icch = (u8)((num/denom) + 1);
  235 + else
  236 + icch = (u8)(num/denom);
  237 +}
  238 +
  239 +/*
  240 + * i2c_read: - Read multiple bytes from an i2c device
  241 + *
  242 + * The higher level routines take into account that this function is only
  243 + * called with len < page length of the device (see configuration file)
  244 + *
  245 + * @chip: address of the chip which is to be read
  246 + * @addr: i2c data address within the chip
  247 + * @alen: length of the i2c data address (1..2 bytes)
  248 + * @buffer: where to write the data
  249 + * @len: how much byte do we want to read
  250 + * @return: 0 in case of success
  251 + */
  252 +int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len)
  253 +{
  254 + int i = 0;
  255 + for (i = 0 ; i < len ; i++)
  256 + buffer[i] = i2c_raw_read(base, chip, addr + i);
  257 +
  258 + return 0;
  259 +}
  260 +
  261 +/*
  262 + * i2c_write: - Write multiple bytes to an i2c device
  263 + *
  264 + * The higher level routines take into account that this function is only
  265 + * called with len < page length of the device (see configuration file)
  266 + *
  267 + * @chip: address of the chip which is to be written
  268 + * @addr: i2c data address within the chip
  269 + * @alen: length of the i2c data address (1..2 bytes)
  270 + * @buffer: where to find the data to be written
  271 + * @len: how much byte do we want to read
  272 + * @return: 0 in case of success
  273 + */
  274 +int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len)
  275 +{
  276 + int i = 0;
  277 + for (i = 0; i < len ; i++)
  278 + i2c_raw_write(base, chip, addr + i, buffer[i]);
  279 +
  280 + return 0;
  281 +}
  282 +
  283 +/*
  284 + * i2c_probe: - Test if a chip answers for a given i2c address
  285 + *
  286 + * @chip: address of the chip which is searched for
  287 + * @return: 0 if a chip was found, -1 otherwhise
  288 + */
  289 +int i2c_probe(u8 chip)
  290 +{
  291 + return 0;
  292 +}