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 --- |