Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "For 3.14, the I2C subsystem has the following to offer:

   - new drivers for Renesas RIIC and RobotFuzz OSIF
   - driver cleanups & improvements & bugfixes

  Pretty standard stuff this time, I'd say.  There is more complex stuff
  coming up, but I didn't have the bandwidth between the years to pull
  it in for this release.  Sadly"

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (26 commits)
  i2c: s3c2410: fix quirk usage for 64-bit
  i2c: pnx: Use devm_*() functions
  i2c: at91: add a new compatibility string for the at91sam9261
  i2c-ismt: support I2C_SMBUS_I2C_BLOCK_DATA transaction type
  i2c: Add bus driver for for OSIF USB i2c device.
  i2c: i2c-tiny-usb: Remove RobotFuzz USB vendor:product ID
  i2c: designware: remove HAVE_CLK build dependecy
  Documentation: i2c: Remove obsolete example
  i2c: nomadik: remove platform data header
  i2c: nomadik: auto-calculate slave setup time
  i2c: viperboard: remove superfluous assignment
  i2c: xilinx: Use devm_* functions
  i2c: xilinx: Do not enable irq before irq handler
  i2c: xilinx: Fix i2c checkpatch warnings
  i2c: at91: document clock properties
  i2c: isch: Use devm_request_region()
  i2c: viperboard: Use devm_kzalloc() functions
  i2c: imx: propagate irq error code in probe
  i2c: s3c2410: dont need CPU_FREQ transitions for exynos series
  i2c: s3c2410: Add polling mode support
  ...
This commit is contained in:
Linus Torvalds 2014-01-21 09:39:37 -08:00
Родитель fb2e2c8537 5f1b11555e
Коммит 02d0a75246
23 изменённых файлов: 966 добавлений и 224 удалений

Просмотреть файл

@ -9,6 +9,7 @@ Required properties :
- interrupts: interrupt number to the cpu.
- #address-cells = <1>;
- #size-cells = <0>;
- clocks: phandles to input clocks.
Optional properties:
- Child nodes conforming to i2c bus binding
@ -21,6 +22,7 @@ i2c0: i2c@fff84000 {
interrupts = <12 4 6>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&twi0_clk>;
24c512@50 {
compatible = "24c512";

Просмотреть файл

@ -0,0 +1,50 @@
* NXP PCA954x I2C bus switch
Required Properties:
- compatible: Must contain one of the following.
"nxp,pca9540", "nxp,pca9542", "nxp,pca9543", "nxp,pca9544",
"nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548"
- reg: The I2C address of the device.
The following required properties are defined externally:
- Standard I2C mux properties. See i2c-mux.txt in this directory.
- I2C child bus nodes. See i2c-mux.txt in this directory.
Optional Properties:
- reset-gpios: Reference to the GPIO connected to the reset input.
Example:
i2c-switch@74 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x74>;
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
eeprom@54 {
compatible = "at,24c08";
reg = <0x54>;
};
};
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
};

Просмотреть файл

@ -0,0 +1,29 @@
Device tree configuration for Renesas RIIC driver
Required properties:
- compatible : "renesas,riic-<soctype>". "renesas,riic-rz" as fallback
- reg : address start and address range size of device
- interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI)
- clock-frequency : frequency of bus clock in Hz
- #address-cells : should be <1>
- #size-cells : should be <0>
Pinctrl properties might be needed, too. See there.
Example:
i2c0: i2c@fcfee000 {
compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
reg = <0xfcfee000 0x44>;
interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
<0 158 IRQ_TYPE_EDGE_RISING>,
<0 159 IRQ_TYPE_EDGE_RISING>,
<0 160 IRQ_TYPE_LEVEL_HIGH>,
<0 161 IRQ_TYPE_LEVEL_HIGH>,
<0 162 IRQ_TYPE_LEVEL_HIGH>,
<0 163 IRQ_TYPE_LEVEL_HIGH>,
<0 164 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
};

Просмотреть файл

@ -10,6 +10,8 @@ Required properties:
inside HDMIPHY block found on several samsung SoCs
(d) "samsung, exynos5440-i2c", for s3c2440-like i2c used
on EXYNOS5440 which does not need GPIO configuration.
(e) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as
a host to SATA PHY controller on an internal bus.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.

Просмотреть файл

@ -64,9 +64,6 @@ EINVAL
detected before any I/O operation was started. Use a more
specific fault code when you can.
One example would be a driver trying an SMBus Block Write
with block size outside the range of 1-32 bytes.
EIO
This rather vague error means something went wrong when
performing an I/O operation. Use a more specific fault

Просмотреть файл

@ -412,7 +412,6 @@ config I2C_DESIGNWARE_CORE
config I2C_DESIGNWARE_PLATFORM
tristate "Synopsys DesignWare Platform"
depends on HAVE_CLK
select I2C_DESIGNWARE_CORE
help
If you say yes to this option, support will be included for the
@ -648,6 +647,16 @@ config I2C_PXA_SLAVE
is necessary for systems where the PXA may be a target on the
I2C bus.
config I2C_RIIC
tristate "Renesas RIIC adapter"
depends on ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
Renesas RIIC I2C interface.
This driver can also be built as a module. If so, the module
will be called i2c-riic.
config HAVE_S3C2410_I2C
bool
help
@ -683,7 +692,7 @@ config I2C_SH7760
config I2C_SH_MOBILE
tristate "SuperH Mobile I2C Controller"
depends on SUPERH || ARM || COMPILE_TEST
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Renesas SH-Mobile processor.
@ -796,7 +805,7 @@ config I2C_XLR
config I2C_RCAR
tristate "Renesas R-Car I2C Controller"
depends on ARM || COMPILE_TEST
depends on ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
R-Car I2C controller.
@ -865,6 +874,16 @@ config I2C_PARPORT_LIGHT
This support is also available as a module. If so, the module
will be called i2c-parport-light.
config I2C_ROBOTFUZZ_OSIF
tristate "RobotFuzz Open Source InterFace USB adapter"
depends on USB
help
If you say yes to this option, support will be included for the
RobotFuzz Open Source InterFace USB to I2C interface.
This driver can also be built as a module. If so, the module
will be called i2c-osif.
config I2C_TAOS_EVM
tristate "TAOS evaluation module"
depends on TTY

Просмотреть файл

@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
@ -83,6 +84,7 @@ obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF) += i2c-robotfuzz-osif.o
obj-$(CONFIG_I2C_TAOS_EVM) += i2c-taos-evm.o
obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
obj-$(CONFIG_I2C_VIPERBOARD) += i2c-viperboard.o

Просмотреть файл

@ -588,6 +588,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
} , {
.compatible = "atmel,at91sam9260-i2c",
.data = &at91sam9260_config,
} , {
.compatible = "atmel,at91sam9261-i2c",
.data = &at91sam9261_config,
} , {
.compatible = "atmel,at91sam9g20-i2c",
.data = &at91sam9g20_config,

Просмотреть файл

@ -26,7 +26,6 @@
*
*/
#include <linux/export.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/i2c.h>

Просмотреть файл

@ -607,7 +607,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "can't get irq number\n");
return -ENOENT;
return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

Просмотреть файл

@ -275,7 +275,8 @@ static int smbus_sch_probe(struct platform_device *dev)
if (!res)
return -EBUSY;
if (!request_region(res->start, resource_size(res), dev->name)) {
if (!devm_request_region(&dev->dev, res->start, resource_size(res),
dev->name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
return -EBUSY;
@ -294,7 +295,6 @@ static int smbus_sch_probe(struct platform_device *dev)
retval = i2c_add_adapter(&sch_adapter);
if (retval) {
dev_err(&dev->dev, "Couldn't register adapter!\n");
release_region(res->start, resource_size(res));
sch_smba = 0;
}
@ -303,11 +303,8 @@ static int smbus_sch_probe(struct platform_device *dev)
static int smbus_sch_remove(struct platform_device *pdev)
{
struct resource *res;
if (sch_smba) {
i2c_del_adapter(&sch_adapter);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, resource_size(res));
sch_smba = 0;
}

Просмотреть файл

@ -344,6 +344,7 @@ static int ismt_process_desc(const struct ismt_desc *desc,
data->word = dma_buffer[0] | (dma_buffer[1] << 8);
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_I2C_BLOCK_DATA:
memcpy(&data->block[1], dma_buffer, desc->rxbytes);
data->block[0] = desc->rxbytes;
break;
@ -509,6 +510,41 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
}
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
/* Make sure the length is valid */
if (data->block[0] < 1)
data->block[0] = 1;
if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
data->block[0] = I2C_SMBUS_BLOCK_MAX;
if (read_write == I2C_SMBUS_WRITE) {
/* i2c Block Write */
dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: WRITE\n");
dma_size = data->block[0] + 1;
dma_direction = DMA_TO_DEVICE;
desc->wr_len_cmd = dma_size;
desc->control |= ISMT_DESC_I2C;
priv->dma_buffer[0] = command;
memcpy(&priv->dma_buffer[1], &data->block[1], dma_size);
} else {
/* i2c Block Read */
dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: READ\n");
dma_size = data->block[0];
dma_direction = DMA_FROM_DEVICE;
desc->rd_len = dma_size;
desc->wr_len_cmd = command;
desc->control |= (ISMT_DESC_I2C | ISMT_DESC_CWRL);
/*
* Per the "Table 15-15. I2C Commands",
* in the External Design Specification (EDS),
* (Document Number: 508084, Revision: 2.0),
* the _rw bit must be 0
*/
desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, 0);
}
break;
default:
dev_err(dev, "Unsupported transaction %d\n",
size);
@ -582,6 +618,7 @@ static u32 ismt_func(struct i2c_adapter *adap)
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_PROC_CALL |
I2C_FUNC_SMBUS_BLOCK_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_PEC;
}

Просмотреть файл

@ -22,7 +22,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/i2c-nomadik.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
@ -104,6 +103,29 @@
/* maximum threshold value */
#define MAX_I2C_FIFO_THRESHOLD 15
enum i2c_freq_mode {
I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
};
/**
* struct nmk_i2c_controller - client specific controller configuration
* @clk_freq: clock frequency for the operation mode
* @tft: Tx FIFO Threshold in bytes
* @rft: Rx FIFO Threshold in bytes
* @timeout Slave response timeout(ms)
* @sm: speed mode
*/
struct nmk_i2c_controller {
u32 clk_freq;
unsigned char tft;
unsigned char rft;
int timeout;
enum i2c_freq_mode sm;
};
/**
* struct i2c_vendor_data - per-vendor variations
* @has_mtdws: variant has the MTDWS bit
@ -340,6 +362,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
{
u32 brcr1, brcr2;
u32 i2c_clk, div;
u32 ns;
u16 slsu;
writel(0x0, dev->virtbase + I2C_CR);
writel(0x0, dev->virtbase + I2C_HSMCR);
@ -347,18 +371,38 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
writel(0x0, dev->virtbase + I2C_RFTR);
writel(0x0, dev->virtbase + I2C_DMAR);
i2c_clk = clk_get_rate(dev->clk);
/*
* set the slsu:
*
* slsu defines the data setup time after SCL clock
* stretching in terms of i2c clk cycles. The
* needed setup time for the three modes are 250ns,
* 100ns, 10ns respectively thus leading to the values
* of 14, 6, 2 for a 48 MHz i2c clk.
* stretching in terms of i2c clk cycles + 1 (zero means
* "wait one cycle"), the needed setup time for the three
* modes are 250ns, 100ns, 10ns respectively.
*
* As the time for one cycle T in nanoseconds is
* T = (1/f) * 1000000000 =>
* slsu = cycles / (1000000000 / f) + 1
*/
writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk);
switch (dev->cfg.sm) {
case I2C_FREQ_MODE_FAST:
case I2C_FREQ_MODE_FAST_PLUS:
slsu = DIV_ROUND_UP(100, ns); /* Fast */
break;
case I2C_FREQ_MODE_HIGH_SPEED:
slsu = DIV_ROUND_UP(10, ns); /* High */
break;
case I2C_FREQ_MODE_STANDARD:
default:
slsu = DIV_ROUND_UP(250, ns); /* Standard */
break;
}
slsu += 1;
i2c_clk = clk_get_rate(dev->clk);
dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu);
writel(slsu << 16, dev->virtbase + I2C_SCR);
/*
* The spec says, in case of std. mode the divider is
@ -915,11 +959,6 @@ static const struct i2c_algorithm nmk_i2c_algo = {
};
static struct nmk_i2c_controller u8500_i2c = {
/*
* Slave data setup time; 250ns, 100ns, and 10ns, which
* is 14, 6 and 2 respectively for a 48Mhz i2c clock.
*/
.slsu = 0xe,
.tft = 1, /* Tx FIFO threshold */
.rft = 8, /* Rx FIFO threshold */
.clk_freq = 400000, /* fast mode operation */
@ -1027,7 +1066,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
/* fetch the controller configuration from machine */
dev->cfg.clk_freq = pdata->clk_freq;
dev->cfg.slsu = pdata->slsu;
dev->cfg.tft = pdata->tft;
dev->cfg.rft = pdata->rft;
dev->cfg.sm = pdata->sm;

Просмотреть файл

@ -628,11 +628,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)
struct resource *res;
u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000;
alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
if (!alg_data) {
ret = -ENOMEM;
goto err_kzalloc;
}
alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL);
if (!alg_data)
return -ENOMEM;
platform_set_drvdata(pdev, alg_data);
@ -657,11 +655,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)
*/
}
#endif
alg_data->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(alg_data->clk)) {
ret = PTR_ERR(alg_data->clk);
goto out_drvdata;
}
alg_data->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(alg_data->clk))
return PTR_ERR(alg_data->clk);
init_timer(&alg_data->mif.timer);
alg_data->mif.timer.function = i2c_pnx_timeout;
@ -672,31 +668,13 @@ static int i2c_pnx_probe(struct platform_device *pdev)
/* Register I/O resource */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Unable to get mem resource.\n");
ret = -EBUSY;
goto out_clkget;
}
if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE,
pdev->name)) {
dev_err(&pdev->dev,
"I/O region 0x%08x for I2C already in use.\n",
res->start);
ret = -ENOMEM;
goto out_clkget;
}
alg_data->base = res->start;
alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE);
if (!alg_data->ioaddr) {
dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
ret = -ENOMEM;
goto out_release;
}
alg_data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(alg_data->ioaddr))
return PTR_ERR(alg_data->ioaddr);
ret = clk_enable(alg_data->clk);
if (ret)
goto out_unmap;
return ret;
freq = clk_get_rate(alg_data->clk);
@ -730,8 +708,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
ret = alg_data->irq;
goto out_clock;
}
ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
0, pdev->name, alg_data);
ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt,
0, pdev->name, alg_data);
if (ret)
goto out_clock;
@ -739,7 +717,7 @@ static int i2c_pnx_probe(struct platform_device *pdev)
ret = i2c_add_numbered_adapter(&alg_data->adapter);
if (ret < 0) {
dev_err(&pdev->dev, "I2C: Failed to add bus\n");
goto out_irq;
goto out_clock;
}
dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
@ -747,19 +725,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
return 0;
out_irq:
free_irq(alg_data->irq, alg_data);
out_clock:
clk_disable(alg_data->clk);
out_unmap:
iounmap(alg_data->ioaddr);
out_release:
release_mem_region(res->start, I2C_PNX_REGION_SIZE);
out_clkget:
clk_put(alg_data->clk);
out_drvdata:
kfree(alg_data);
err_kzalloc:
return ret;
}
@ -767,13 +734,8 @@ static int i2c_pnx_remove(struct platform_device *pdev)
{
struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
free_irq(alg_data->irq, alg_data);
i2c_del_adapter(&alg_data->adapter);
clk_disable(alg_data->clk);
iounmap(alg_data->ioaddr);
release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
clk_put(alg_data->clk);
kfree(alg_data);
return 0;
}

Просмотреть файл

@ -0,0 +1,427 @@
/*
* Renesas RIIC driver
*
* Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
* Copyright (C) 2013 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
/*
* This i2c core has a lot of interrupts, namely 8. We use their chaining as
* some kind of state machine.
*
* 1) The main xfer routine kicks off a transmission by putting the start bit
* (or repeated start) on the bus and enabling the transmit interrupt (TIE)
* since we need to send the slave address + RW bit in every case.
*
* 2) TIE sends slave address + RW bit and selects how to continue.
*
* 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
* are done, we switch over to the transmission done interrupt (TEIE) and mark
* the message as completed (includes sending STOP) there.
*
* 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is
* needed to start clocking, then we keep receiving until we are done. Note
* that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by
* writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a
* message to create the final NACK as sketched in the datasheet. This caused
* some subtle races (when byte n was processed and byte n+1 was already
* waiting), though, and I started with the safe approach.
*
* 4) If we got a NACK somewhere, we flag the error and stop the transmission
* via NAKIE.
*
* Also check the comments in the interrupt routines for some gory details.
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#define RIIC_ICCR1 0x00
#define RIIC_ICCR2 0x04
#define RIIC_ICMR1 0x08
#define RIIC_ICMR3 0x10
#define RIIC_ICSER 0x18
#define RIIC_ICIER 0x1c
#define RIIC_ICSR2 0x24
#define RIIC_ICBRL 0x34
#define RIIC_ICBRH 0x38
#define RIIC_ICDRT 0x3c
#define RIIC_ICDRR 0x40
#define ICCR1_ICE 0x80
#define ICCR1_IICRST 0x40
#define ICCR1_SOWP 0x10
#define ICCR2_BBSY 0x80
#define ICCR2_SP 0x08
#define ICCR2_RS 0x04
#define ICCR2_ST 0x02
#define ICMR1_CKS_MASK 0x70
#define ICMR1_BCWP 0x08
#define ICMR1_CKS(_x) ((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP)
#define ICMR3_RDRFS 0x20
#define ICMR3_ACKWP 0x10
#define ICMR3_ACKBT 0x08
#define ICIER_TIE 0x80
#define ICIER_TEIE 0x40
#define ICIER_RIE 0x20
#define ICIER_NAKIE 0x10
#define ICSR2_NACKF 0x10
/* ICBRx (@ PCLK 33MHz) */
#define ICBR_RESERVED 0xe0 /* Should be 1 on writes */
#define ICBRL_SP100K (19 | ICBR_RESERVED)
#define ICBRH_SP100K (16 | ICBR_RESERVED)
#define ICBRL_SP400K (21 | ICBR_RESERVED)
#define ICBRH_SP400K (9 | ICBR_RESERVED)
#define RIIC_INIT_MSG -1
struct riic_dev {
void __iomem *base;
u8 *buf;
struct i2c_msg *msg;
int bytes_left;
int err;
int is_last;
struct completion msg_done;
struct i2c_adapter adapter;
struct clk *clk;
};
struct riic_irq_desc {
int res_num;
irq_handler_t isr;
char *name;
};
static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
{
writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg);
}
static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
struct riic_dev *riic = i2c_get_adapdata(adap);
unsigned long time_left;
int i, ret;
u8 start_bit;
ret = clk_prepare_enable(riic->clk);
if (ret)
return ret;
if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) {
riic->err = -EBUSY;
goto out;
}
reinit_completion(&riic->msg_done);
riic->err = 0;
writeb(0, riic->base + RIIC_ICSR2);
for (i = 0, start_bit = ICCR2_ST; i < num; i++) {
riic->bytes_left = RIIC_INIT_MSG;
riic->buf = msgs[i].buf;
riic->msg = &msgs[i];
riic->is_last = (i == num - 1);
writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER);
writeb(start_bit, riic->base + RIIC_ICCR2);
time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout);
if (time_left == 0)
riic->err = -ETIMEDOUT;
if (riic->err)
break;
start_bit = ICCR2_RS;
}
out:
clk_disable_unprepare(riic->clk);
return riic->err ?: num;
}
static irqreturn_t riic_tdre_isr(int irq, void *data)
{
struct riic_dev *riic = data;
u8 val;
if (!riic->bytes_left)
return IRQ_NONE;
if (riic->bytes_left == RIIC_INIT_MSG) {
val = !!(riic->msg->flags & I2C_M_RD);
if (val)
/* On read, switch over to receive interrupt */
riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER);
else
/* On write, initialize length */
riic->bytes_left = riic->msg->len;
val |= (riic->msg->addr << 1);
} else {
val = *riic->buf;
riic->buf++;
riic->bytes_left--;
}
/*
* Switch to transmission ended interrupt when done. Do check here
* after bytes_left was initialized to support SMBUS_QUICK (new msg has
* 0 length then)
*/
if (riic->bytes_left == 0)
riic_clear_set_bit(riic, ICIER_TIE, ICIER_TEIE, RIIC_ICIER);
/*
* This acks the TIE interrupt. We get another TIE immediately if our
* value could be moved to the shadow shift register right away. So
* this must be after updates to ICIER (where we want to disable TIE)!
*/
writeb(val, riic->base + RIIC_ICDRT);
return IRQ_HANDLED;
}
static irqreturn_t riic_tend_isr(int irq, void *data)
{
struct riic_dev *riic = data;
if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) {
/* We got a NACKIE */
readb(riic->base + RIIC_ICDRR); /* dummy read */
riic->err = -ENXIO;
} else if (riic->bytes_left) {
return IRQ_NONE;
}
if (riic->is_last || riic->err)
writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
writeb(0, riic->base + RIIC_ICIER);
complete(&riic->msg_done);
return IRQ_HANDLED;
}
static irqreturn_t riic_rdrf_isr(int irq, void *data)
{
struct riic_dev *riic = data;
if (!riic->bytes_left)
return IRQ_NONE;
if (riic->bytes_left == RIIC_INIT_MSG) {
riic->bytes_left = riic->msg->len;
readb(riic->base + RIIC_ICDRR); /* dummy read */
return IRQ_HANDLED;
}
if (riic->bytes_left == 1) {
/* STOP must come before we set ACKBT! */
if (riic->is_last)
writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3);
writeb(0, riic->base + RIIC_ICIER);
complete(&riic->msg_done);
} else {
riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3);
}
/* Reading acks the RIE interrupt */
*riic->buf = readb(riic->base + RIIC_ICDRR);
riic->buf++;
riic->bytes_left--;
return IRQ_HANDLED;
}
static u32 riic_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static const struct i2c_algorithm riic_algo = {
.master_xfer = riic_xfer,
.functionality = riic_func,
};
static int riic_init_hw(struct riic_dev *riic, u32 spd)
{
int ret;
unsigned long rate;
ret = clk_prepare_enable(riic->clk);
if (ret)
return ret;
/*
* TODO: Implement formula to calculate the timing values depending on
* variable parent clock rate and arbitrary bus speed
*/
rate = clk_get_rate(riic->clk);
if (rate != 33325000) {
dev_err(&riic->adapter.dev,
"invalid parent clk (%lu). Must be 33325000Hz\n", rate);
clk_disable_unprepare(riic->clk);
return -EINVAL;
}
/* Changing the order of accessing IICRST and ICE may break things! */
writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1);
riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1);
switch (spd) {
case 100000:
writeb(ICMR1_CKS(3), riic->base + RIIC_ICMR1);
writeb(ICBRH_SP100K, riic->base + RIIC_ICBRH);
writeb(ICBRL_SP100K, riic->base + RIIC_ICBRL);
break;
case 400000:
writeb(ICMR1_CKS(1), riic->base + RIIC_ICMR1);
writeb(ICBRH_SP400K, riic->base + RIIC_ICBRH);
writeb(ICBRL_SP400K, riic->base + RIIC_ICBRL);
break;
default:
dev_err(&riic->adapter.dev,
"unsupported bus speed (%dHz). Use 100000 or 400000\n", spd);
clk_disable_unprepare(riic->clk);
return -EINVAL;
}
writeb(0, riic->base + RIIC_ICSER);
writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3);
riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1);
clk_disable_unprepare(riic->clk);
return 0;
}
static struct riic_irq_desc riic_irqs[] = {
{ .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" },
{ .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" },
{ .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" },
{ .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" },
};
static int riic_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct riic_dev *riic;
struct i2c_adapter *adap;
struct resource *res;
u32 bus_rate = 0;
int i, ret;
riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
if (!riic)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
riic->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(riic->base))
return PTR_ERR(riic->base);
riic->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(riic->clk)) {
dev_err(&pdev->dev, "missing controller clock");
return PTR_ERR(riic->clk);
}
for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
if (!res)
return -ENODEV;
ret = devm_request_irq(&pdev->dev, res->start, riic_irqs[i].isr,
0, riic_irqs[i].name, riic);
if (ret) {
dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name);
return ret;
}
}
adap = &riic->adapter;
i2c_set_adapdata(adap, riic);
strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
adap->owner = THIS_MODULE;
adap->algo = &riic_algo;
adap->dev.parent = &pdev->dev;
adap->dev.of_node = pdev->dev.of_node;
init_completion(&riic->msg_done);
of_property_read_u32(np, "clock-frequency", &bus_rate);
ret = riic_init_hw(riic, bus_rate);
if (ret)
return ret;
ret = i2c_add_adapter(adap);
if (ret) {
dev_err(&pdev->dev, "failed to add adapter\n");
return ret;
}
platform_set_drvdata(pdev, riic);
dev_info(&pdev->dev, "registered with %dHz bus speed\n", bus_rate);
return 0;
}
static int riic_i2c_remove(struct platform_device *pdev)
{
struct riic_dev *riic = platform_get_drvdata(pdev);
writeb(0, riic->base + RIIC_ICIER);
i2c_del_adapter(&riic->adapter);
return 0;
}
static struct of_device_id riic_i2c_dt_ids[] = {
{ .compatible = "renesas,riic-rz" },
{ /* Sentinel */ },
};
static struct platform_driver riic_i2c_driver = {
.probe = riic_i2c_probe,
.remove = riic_i2c_remove,
.driver = {
.name = "i2c-riic",
.owner = THIS_MODULE,
.of_match_table = riic_i2c_dt_ids,
},
};
module_platform_driver(riic_i2c_driver);
MODULE_DESCRIPTION("Renesas RIIC adapter");
MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, riic_i2c_dt_ids);

Просмотреть файл

@ -0,0 +1,202 @@
/*
* Driver for RobotFuzz OSIF
*
* Copyright (c) 2013 Andrew Lunn <andrew@lunn.ch>
* Copyright (c) 2007 Barry Carter <Barry.Carter@robotfuzz.com>
*
* Based on the i2c-tiny-usb by
*
* Copyright (C) 2006 Til Harbaum (Till@Harbaum.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/usb.h>
#define OSIFI2C_READ 20
#define OSIFI2C_WRITE 21
#define OSIFI2C_STOP 22
#define OSIFI2C_STATUS 23
#define OSIFI2C_SET_BIT_RATE 24
#define STATUS_ADDRESS_ACK 0
#define STATUS_ADDRESS_NAK 2
struct osif_priv {
struct usb_device *usb_dev;
struct usb_interface *interface;
struct i2c_adapter adapter;
unsigned char status;
};
static int osif_usb_read(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct osif_priv *priv = adapter->algo_data;
return usb_control_msg(priv->usb_dev, usb_rcvctrlpipe(priv->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
USB_DIR_IN, value, index, data, len, 2000);
}
static int osif_usb_write(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct osif_priv *priv = adapter->algo_data;
return usb_control_msg(priv->usb_dev, usb_sndctrlpipe(priv->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
value, index, data, len, 2000);
}
static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
int num)
{
struct osif_priv *priv = adapter->algo_data;
struct i2c_msg *pmsg;
int ret = 0;
int i, cmd;
for (i = 0; ret >= 0 && i < num; i++) {
pmsg = &msgs[i];
if (pmsg->flags & I2C_M_RD) {
cmd = OSIFI2C_READ;
ret = osif_usb_read(adapter, cmd, pmsg->flags,
pmsg->addr, pmsg->buf,
pmsg->len);
if (ret != pmsg->len) {
dev_err(&adapter->dev, "failure reading data\n");
return -EREMOTEIO;
}
} else {
cmd = OSIFI2C_WRITE;
ret = osif_usb_write(adapter, cmd, pmsg->flags,
pmsg->addr, pmsg->buf, pmsg->len);
if (ret != pmsg->len) {
dev_err(&adapter->dev, "failure writing data\n");
return -EREMOTEIO;
}
}
ret = osif_usb_read(adapter, OSIFI2C_STOP, 0, 0, NULL, 0);
if (ret) {
dev_err(&adapter->dev, "failure sending STOP\n");
return -EREMOTEIO;
}
/* read status */
ret = osif_usb_read(adapter, OSIFI2C_STATUS, 0, 0,
&priv->status, 1);
if (ret != 1) {
dev_err(&adapter->dev, "failure reading status\n");
return -EREMOTEIO;
}
if (priv->status != STATUS_ADDRESS_ACK) {
dev_dbg(&adapter->dev, "status = %d\n", priv->status);
return -EREMOTEIO;
}
}
return i;
}
static u32 osif_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm osif_algorithm = {
.master_xfer = osif_xfer,
.functionality = osif_func,
};
#define USB_OSIF_VENDOR_ID 0x1964
#define USB_OSIF_PRODUCT_ID 0x0001
static struct usb_device_id osif_table[] = {
{ USB_DEVICE(USB_OSIF_VENDOR_ID, USB_OSIF_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, osif_table);
static int osif_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
int ret;
struct osif_priv *priv;
u16 version;
priv = devm_kzalloc(&interface->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->usb_dev = usb_get_dev(interface_to_usbdev(interface));
priv->interface = interface;
usb_set_intfdata(interface, priv);
priv->adapter.owner = THIS_MODULE;
priv->adapter.class = I2C_CLASS_HWMON;
priv->adapter.algo = &osif_algorithm;
priv->adapter.algo_data = priv;
snprintf(priv->adapter.name, sizeof(priv->adapter.name),
"OSIF at bus %03d device %03d",
priv->usb_dev->bus->busnum, priv->usb_dev->devnum);
/*
* Set bus frequency. The frequency is:
* 120,000,000 / ( 16 + 2 * div * 4^prescale).
* Using dev = 52, prescale = 0 give 100KHz */
ret = osif_usb_read(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0,
NULL, 0);
if (ret) {
dev_err(&interface->dev, "failure sending bit rate");
usb_put_dev(priv->usb_dev);
return ret;
}
i2c_add_adapter(&(priv->adapter));
version = le16_to_cpu(priv->usb_dev->descriptor.bcdDevice);
dev_info(&interface->dev,
"version %x.%02x found at bus %03d address %03d",
version >> 8, version & 0xff,
priv->usb_dev->bus->busnum, priv->usb_dev->devnum);
return 0;
}
static void osif_disconnect(struct usb_interface *interface)
{
struct osif_priv *priv = usb_get_intfdata(interface);
i2c_del_adapter(&(priv->adapter));
usb_set_intfdata(interface, NULL);
usb_put_dev(priv->usb_dev);
}
static struct usb_driver osif_driver = {
.name = "RobotFuzz Open Source InterFace, OSIF",
.probe = osif_probe,
.disconnect = osif_disconnect,
.id_table = osif_table,
};
module_usb_driver(osif_driver);
MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
MODULE_AUTHOR("Barry Carter <barry.carter@robotfuzz.com>");
MODULE_DESCRIPTION("RobotFuzz OSIF driver");
MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -86,6 +86,7 @@
#define QUIRK_S3C2440 (1 << 0)
#define QUIRK_HDMIPHY (1 << 1)
#define QUIRK_NO_GPIO (1 << 2)
#define QUIRK_POLL (1 << 3)
/* Max time to wait for bus to become idle after a xfer (in us) */
#define S3C2410_IDLE_TIMEOUT 5000
@ -101,7 +102,7 @@ enum s3c24xx_i2c_state {
struct s3c24xx_i2c {
wait_queue_head_t wait;
unsigned int quirks;
kernel_ulong_t quirks;
unsigned int suspended:1;
struct i2c_msg *msg;
@ -123,7 +124,7 @@ struct s3c24xx_i2c {
struct s3c2410_platform_i2c *pdata;
int gpios[2];
struct pinctrl *pctrl;
#ifdef CONFIG_CPU_FREQ
#if defined(CONFIG_ARM_S3C24XX_CPUFREQ)
struct notifier_block freq_transition;
#endif
};
@ -142,6 +143,8 @@ static struct platform_device_id s3c24xx_driver_ids[] = {
};
MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat);
#ifdef CONFIG_OF
static const struct of_device_id s3c24xx_i2c_match[] = {
{ .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
@ -150,6 +153,8 @@ static const struct of_device_id s3c24xx_i2c_match[] = {
.data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
{ .compatible = "samsung,exynos5440-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_NO_GPIO) },
{ .compatible = "samsung,exynos5-sata-phy-i2c",
.data = (void *)(QUIRK_S3C2440 | QUIRK_POLL | QUIRK_NO_GPIO) },
{},
};
MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
@ -160,12 +165,12 @@ MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
* Get controller type either from device tree or platform device variant.
*/
static inline unsigned int s3c24xx_get_device_quirks(struct platform_device *pdev)
static inline kernel_ulong_t s3c24xx_get_device_quirks(struct platform_device *pdev)
{
if (pdev->dev.of_node) {
const struct of_device_id *match;
match = of_match_node(s3c24xx_i2c_match, pdev->dev.of_node);
return (unsigned int)match->data;
return (kernel_ulong_t)match->data;
}
return platform_get_device_id(pdev)->driver_data;
@ -188,7 +193,8 @@ static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
if (ret)
i2c->msg_idx = ret;
wake_up(&i2c->wait);
if (!(i2c->quirks & QUIRK_POLL))
wake_up(&i2c->wait);
}
static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
@ -225,6 +231,22 @@ static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
}
static bool is_ack(struct s3c24xx_i2c *i2c)
{
int tries;
for (tries = 50; tries; --tries) {
if (readl(i2c->regs + S3C2410_IICCON)
& S3C2410_IICCON_IRQPEND) {
if (!(readl(i2c->regs + S3C2410_IICSTAT)
& S3C2410_IICSTAT_LASTBIT))
return true;
}
usleep_range(1000, 2000);
}
dev_err(i2c->dev, "ack was not recieved\n");
return false;
}
/* s3c24xx_i2c_message_start
*
@ -269,6 +291,16 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
stat |= S3C2410_IICSTAT_START;
writel(stat, i2c->regs + S3C2410_IICSTAT);
if (i2c->quirks & QUIRK_POLL) {
while ((i2c->msg_num != 0) && is_ack(i2c)) {
i2c_s3c_irq_nextbyte(i2c, stat);
stat = readl(i2c->regs + S3C2410_IICSTAT);
if (stat & S3C2410_IICSTAT_ARBITR)
dev_err(i2c->dev, "deal with arbitration loss\n");
}
}
}
static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
@ -676,6 +708,15 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
s3c24xx_i2c_enable_irq(i2c);
s3c24xx_i2c_message_start(i2c, msgs);
if (i2c->quirks & QUIRK_POLL) {
ret = i2c->msg_idx;
if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
goto out;
}
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
ret = i2c->msg_idx;
@ -821,6 +862,9 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
if (div1 == 512)
iiccon |= S3C2410_IICCON_TXDIV_512;
if (i2c->quirks & QUIRK_POLL)
iiccon |= S3C2410_IICCON_SCALE(2);
writel(iiccon, i2c->regs + S3C2410_IICCON);
if (i2c->quirks & QUIRK_S3C2440) {
@ -843,7 +887,7 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got)
return 0;
}
#ifdef CONFIG_CPU_FREQ
#if defined(CONFIG_ARM_S3C24XX_CPUFREQ)
#define freq_to_i2c(_n) container_of(_n, struct s3c24xx_i2c, freq_transition)
@ -1118,18 +1162,20 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
* ensure no current IRQs pending
*/
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
return ret;
}
if (!(i2c->quirks & QUIRK_POLL)) {
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
return ret;
}
ret = devm_request_irq(&pdev->dev, i2c->irq, s3c24xx_i2c_irq, 0,
dev_name(&pdev->dev), i2c);
dev_name(&pdev->dev), i2c);
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
return ret;
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
return ret;
}
}
ret = s3c24xx_i2c_register_cpufreq(i2c);

Просмотреть файл

@ -162,7 +162,6 @@ static const struct i2c_algorithm usb_algorithm = {
static const struct usb_device_id i2c_tiny_usb_table[] = {
{ USB_DEVICE(0x0403, 0xc631) }, /* FTDI */
{ USB_DEVICE(0x1c40, 0x0534) }, /* EZPrototypes */
{ USB_DEVICE(0x1964, 0x0001) }, /* Robofuzz OSIF */
{ } /* Terminating entry */
};

Просмотреть файл

@ -118,8 +118,7 @@ static int vprbrd_i2c_addr(struct usb_device *usb_dev,
static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg)
{
int ret;
u16 remain_len, bytes_xfer, len1, len2,
start = 0x0000;
u16 remain_len, len1, len2, start = 0x0000;
struct vprbrd_i2c_read_msg *rmsg =
(struct vprbrd_i2c_read_msg *)vb->buf;
@ -166,7 +165,6 @@ static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg)
rmsg->header.len3 = remain_len - 512;
rmsg->header.len4 = 0x00;
rmsg->header.len5 = 0x00;
bytes_xfer = remain_len;
remain_len = 0;
} else if (remain_len <= 1022) {
len1 = 512;
@ -367,7 +365,7 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
int ret;
int pipe;
vb_i2c = kzalloc(sizeof(*vb_i2c), GFP_KERNEL);
vb_i2c = devm_kzalloc(&pdev->dev, sizeof(*vb_i2c), GFP_KERNEL);
if (vb_i2c == NULL)
return -ENOMEM;
@ -394,14 +392,12 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
if (ret != 1) {
dev_err(&pdev->dev,
"failure setting i2c_bus_freq to %d\n", i2c_bus_freq);
ret = -EIO;
goto error;
return -EIO;
}
} else {
dev_err(&pdev->dev,
"invalid i2c_bus_freq setting:%d\n", i2c_bus_freq);
ret = -EIO;
goto error;
return -EIO;
}
vb_i2c->i2c.dev.parent = &pdev->dev;
@ -412,10 +408,6 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, vb_i2c);
return 0;
error:
kfree(vb_i2c);
return ret;
}
static int vprbrd_i2c_remove(struct platform_device *pdev)

Просмотреть файл

@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
@ -69,7 +70,7 @@ struct xiic_i2c {
struct i2c_adapter adap;
struct i2c_msg *tx_msg;
spinlock_t lock;
unsigned int tx_pos;
unsigned int tx_pos;
unsigned int nmsgs;
enum xilinx_i2c_state state;
struct i2c_msg *rx_msg;
@ -272,8 +273,8 @@ static void xiic_read_rx(struct xiic_i2c *i2c)
bytes_in_fifo = xiic_getreg8(i2c, XIIC_RFO_REG_OFFSET) + 1;
dev_dbg(i2c->adap.dev.parent, "%s entry, bytes in fifo: %d, msg: %d"
", SR: 0x%x, CR: 0x%x\n",
dev_dbg(i2c->adap.dev.parent,
"%s entry, bytes in fifo: %d, msg: %d, SR: 0x%x, CR: 0x%x\n",
__func__, bytes_in_fifo, xiic_rx_space(i2c),
xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
@ -340,9 +341,10 @@ static void xiic_process(struct xiic_i2c *i2c)
ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET);
pend = isr & ier;
dev_dbg(i2c->adap.dev.parent, "%s entry, IER: 0x%x, ISR: 0x%x, "
"pend: 0x%x, SR: 0x%x, msg: %p, nmsgs: %d\n",
__func__, ier, isr, pend, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
dev_dbg(i2c->adap.dev.parent, "%s: IER: 0x%x, ISR: 0x%x, pend: 0x%x\n",
__func__, ier, isr, pend);
dev_dbg(i2c->adap.dev.parent, "%s: SR: 0x%x, msg: %p, nmsgs: %d\n",
__func__, xiic_getreg8(i2c, XIIC_SR_REG_OFFSET),
i2c->tx_msg, i2c->nmsgs);
/* Do not processes a devices interrupts if the device has no
@ -542,9 +544,10 @@ static void xiic_start_send(struct xiic_i2c *i2c)
xiic_irq_clr(i2c, XIIC_INTR_TX_ERROR_MASK);
dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d, "
"ISR: 0x%x, CR: 0x%x\n",
__func__, msg, msg->len, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, len: %d",
__func__, msg, msg->len);
dev_dbg(i2c->adap.dev.parent, "%s entry, ISR: 0x%x, CR: 0x%x\n",
__func__, xiic_getreg32(i2c, XIIC_IISR_OFFSET),
xiic_getreg8(i2c, XIIC_CR_REG_OFFSET));
if (!(msg->flags & I2C_M_NOSTART)) {
@ -695,32 +698,20 @@ static int xiic_i2c_probe(struct platform_device *pdev)
int ret, irq;
u8 i;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
goto resource_missing;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
goto resource_missing;
pdata = dev_get_platdata(&pdev->dev);
i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "Memory region busy\n");
ret = -EBUSY;
goto request_mem_failed;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
i2c->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base);
i2c->base = ioremap(res->start, resource_size(res));
if (!i2c->base) {
dev_err(&pdev->dev, "Unable to map registers\n");
ret = -EIO;
goto map_failed;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
pdata = dev_get_platdata(&pdev->dev);
/* hook up driver to tree */
platform_set_drvdata(pdev, i2c);
@ -729,21 +720,23 @@ static int xiic_i2c_probe(struct platform_device *pdev)
i2c->adap.dev.parent = &pdev->dev;
i2c->adap.dev.of_node = pdev->dev.of_node;
xiic_reinit(i2c);
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
ret = request_irq(irq, xiic_isr, 0, pdev->name, i2c);
if (ret) {
ret = devm_request_irq(&pdev->dev, irq, xiic_isr, 0, pdev->name, i2c);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto request_irq_failed;
return ret;
}
xiic_reinit(i2c);
/* add i2c adapter to i2c tree */
ret = i2c_add_adapter(&i2c->adap);
if (ret) {
dev_err(&pdev->dev, "Failed to add adapter\n");
goto add_adapter_failed;
xiic_deinit(i2c);
return ret;
}
if (pdata) {
@ -753,43 +746,17 @@ static int xiic_i2c_probe(struct platform_device *pdev)
}
return 0;
add_adapter_failed:
free_irq(irq, i2c);
request_irq_failed:
xiic_deinit(i2c);
iounmap(i2c->base);
map_failed:
release_mem_region(res->start, resource_size(res));
request_mem_failed:
kfree(i2c);
return ret;
resource_missing:
dev_err(&pdev->dev, "IRQ or Memory resource is missing\n");
return -ENOENT;
}
static int xiic_i2c_remove(struct platform_device *pdev)
{
struct xiic_i2c *i2c = platform_get_drvdata(pdev);
struct resource *res;
/* remove adapter & data */
i2c_del_adapter(&i2c->adap);
xiic_deinit(i2c);
free_irq(platform_get_irq(pdev, 0), i2c);
iounmap(i2c->base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, resource_size(res));
kfree(i2c);
return 0;
}

Просмотреть файл

@ -35,14 +35,15 @@
* warranty of any kind, whether express or implied.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
#define PCA954X_MAX_NCHANS 8
@ -186,28 +187,43 @@ static int pca954x_probe(struct i2c_client *client,
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = client->dev.of_node;
int num, force, class;
struct pca954x *data;
int ret = -ENODEV;
int ret;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto err;
return -ENODEV;
data = kzalloc(sizeof(struct pca954x), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto err;
}
data = devm_kzalloc(&client->dev, sizeof(struct pca954x), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
if (IS_ENABLED(CONFIG_OF) && np) {
enum of_gpio_flags flags;
int gpio;
/* Get the mux out of reset if a reset GPIO is specified. */
gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
if (gpio_is_valid(gpio)) {
ret = devm_gpio_request_one(&client->dev, gpio,
flags & OF_GPIO_ACTIVE_LOW ?
GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
"pca954x reset");
if (ret < 0)
return ret;
}
}
/* Write the mux register at addr to verify
* that the mux is in fact present. This also
* initializes the mux to disconnected state.
*/
if (i2c_smbus_write_byte(client, 0) < 0) {
dev_warn(&client->dev, "probe failed\n");
goto exit_free;
return -ENODEV;
}
data->type = id->driver_data;
@ -252,9 +268,6 @@ static int pca954x_probe(struct i2c_client *client,
virt_reg_failed:
for (num--; num >= 0; num--)
i2c_del_mux_adapter(data->virt_adaps[num]);
exit_free:
kfree(data);
err:
return ret;
}
@ -270,7 +283,6 @@ static int pca954x_remove(struct i2c_client *client)
data->virt_adaps[i] = NULL;
}
kfree(data);
return 0;
}

Просмотреть файл

@ -31,7 +31,6 @@ struct i2c_pnx_algo_data {
int last;
struct clk *clk;
struct i2c_adapter adapter;
phys_addr_t base;
int irq;
u32 timeout;
};

Просмотреть файл

@ -1,39 +0,0 @@
/*
* Copyright (C) 2009 ST-Ericsson
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*/
#ifndef __PDATA_I2C_NOMADIK_H
#define __PDATA_I2C_NOMADIK_H
enum i2c_freq_mode {
I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
};
/**
* struct nmk_i2c_controller - client specific controller configuration
* @clk_freq: clock frequency for the operation mode
* @slsu: Slave data setup time in ns.
* The needed setup time for three modes of operation
* are 250ns, 100ns and 10ns respectively thus leading
* to the values of 14, 6, 2 for a 48 MHz i2c clk
* @tft: Tx FIFO Threshold in bytes
* @rft: Rx FIFO Threshold in bytes
* @timeout Slave response timeout(ms)
* @sm: speed mode
*/
struct nmk_i2c_controller {
u32 clk_freq;
unsigned short slsu;
unsigned char tft;
unsigned char rft;
int timeout;
enum i2c_freq_mode sm;
};
#endif /* __PDATA_I2C_NOMADIK_H */