i2c-iop3xx.c (5800571960234f9d1f1011bf135799b2014d4268) i2c-iop3xx.c (fdb7e884ad617f8aa69abdd7f39e3fdac85e081e)
1// SPDX-License-Identifier: GPL-2.0-only
2/* ------------------------------------------------------------------------- */
3/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */
4/* ------------------------------------------------------------------------- */
5/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
6 * <Peter dot Milne at D hyphen TACQ dot com>
7 *
8 * With acknowledgements to i2c-algo-ibm_ocp.c by
9 * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com

--- 9 unchanged lines hidden (view full) ---

19 *
20 * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs
21 * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference
22 * - Make it work with IXP46x chips
23 * - Cleanup function names, coding style, etc
24 *
25 * - writing to slave address causes latchup on iop331.
26 * fix: driver refuses to address self.
1/* ------------------------------------------------------------------------- */
2/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx & IXP46x */
3/* ------------------------------------------------------------------------- */
4/* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
5 * <Peter dot Milne at D hyphen TACQ dot com>
6 *
7 * With acknowledgements to i2c-algo-ibm_ocp.c by
8 * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com

--- 9 unchanged lines hidden (view full) ---

18 *
19 * - Use driver model to pass per-chip info instead of hardcoding and #ifdefs
20 * - Use ioremap/__raw_readl/__raw_writel instead of direct dereference
21 * - Make it work with IXP46x chips
22 * - Cleanup function names, coding style, etc
23 *
24 * - writing to slave address causes latchup on iop331.
25 * fix: driver refuses to address self.
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation, version 2.
27 */
28
29#include <linux/interrupt.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/delay.h>
33#include <linux/slab.h>
34#include <linux/errno.h>
35#include <linux/platform_device.h>
36#include <linux/i2c.h>
37#include <linux/io.h>
30 */
31
32#include <linux/interrupt.h>
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/delay.h>
36#include <linux/slab.h>
37#include <linux/errno.h>
38#include <linux/platform_device.h>
39#include <linux/i2c.h>
40#include <linux/io.h>
38#include <linux/gpio.h>
41#include <linux/gpio/consumer.h>
39
40#include "i2c-iop3xx.h"
41
42/* global unit counter */
43static int i2c_id;
44
45static inline unsigned char
46iic_cook_addr(struct i2c_msg *msg)

--- 16 unchanged lines hidden (view full) ---

63
64static void
65iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
66{
67 u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
68
69 /*
70 * Every time unit enable is asserted, GPOD needs to be cleared
42
43#include "i2c-iop3xx.h"
44
45/* global unit counter */
46static int i2c_id;
47
48static inline unsigned char
49iic_cook_addr(struct i2c_msg *msg)

--- 16 unchanged lines hidden (view full) ---

66
67static void
68iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
69{
70 u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
71
72 /*
73 * Every time unit enable is asserted, GPOD needs to be cleared
71 * on IOP3XX to avoid data corruption on the bus.
74 * on IOP3XX to avoid data corruption on the bus. We use the
75 * gpiod_set_raw_value() to make sure the 0 hits the hardware
76 * GPOD register. These descriptors are only passed along to
77 * the device if this is necessary.
72 */
78 */
73#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
74 if (iop3xx_adap->id == 0) {
75 gpio_set_value(7, 0);
76 gpio_set_value(6, 0);
77 } else {
78 gpio_set_value(5, 0);
79 gpio_set_value(4, 0);
80 }
81#endif
79 if (iop3xx_adap->gpio_scl)
80 gpiod_set_raw_value(iop3xx_adap->gpio_scl, 0);
81 if (iop3xx_adap->gpio_sda)
82 gpiod_set_raw_value(iop3xx_adap->gpio_sda, 0);
83
82 /* NB SR bits not same position as CR IE bits :-( */
83 iop3xx_adap->SR_enabled =
84 IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
85 IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
86
87 cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
88 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
89

--- 336 unchanged lines hidden (view full) ---

426 }
427
428 adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
429 if (!adapter_data) {
430 ret = -ENOMEM;
431 goto free_adapter;
432 }
433
84 /* NB SR bits not same position as CR IE bits :-( */
85 iop3xx_adap->SR_enabled =
86 IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
87 IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
88
89 cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
90 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
91

--- 336 unchanged lines hidden (view full) ---

428 }
429
430 adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
431 if (!adapter_data) {
432 ret = -ENOMEM;
433 goto free_adapter;
434 }
435
436 adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev,
437 "scl",
438 GPIOD_ASIS);
439 if (IS_ERR(adapter_data->gpio_scl))
440 return PTR_ERR(adapter_data->gpio_scl);
441 adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev,
442 "sda",
443 GPIOD_ASIS);
444 if (IS_ERR(adapter_data->gpio_sda))
445 return PTR_ERR(adapter_data->gpio_sda);
446
434 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
435 if (!res) {
436 ret = -ENODEV;
437 goto free_both;
438 }
439
440 if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
441 ret = -EBUSY;

--- 89 unchanged lines hidden ---
447 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
448 if (!res) {
449 ret = -ENODEV;
450 goto free_both;
451 }
452
453 if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
454 ret = -EBUSY;

--- 89 unchanged lines hidden ---