root/drivers/i2c/busses/i2c-iop3xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iic_cook_addr
  2. iop3xx_i2c_reset
  3. iop3xx_i2c_enable
  4. iop3xx_i2c_transaction_cleanup
  5. iop3xx_i2c_irq_handler
  6. iop3xx_i2c_error
  7. iop3xx_i2c_get_srstat
  8. iop3xx_i2c_wait_event
  9. all_bits_clear
  10. any_bits_set
  11. iop3xx_i2c_wait_tx_done
  12. iop3xx_i2c_wait_rx_done
  13. iop3xx_i2c_wait_idle
  14. iop3xx_i2c_send_target_addr
  15. iop3xx_i2c_write_byte
  16. iop3xx_i2c_read_byte
  17. iop3xx_i2c_writebytes
  18. iop3xx_i2c_readbytes
  19. iop3xx_i2c_handle_msg
  20. iop3xx_i2c_master_xfer
  21. iop3xx_i2c_func
  22. iop3xx_i2c_remove
  23. iop3xx_i2c_probe

   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
  10  *
  11  * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
  12  *
  13  * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
  14  *
  15  * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
  16  * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
  17  *
  18  * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
  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.
  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>
  38 #include <linux/gpio/consumer.h>
  39 
  40 #include "i2c-iop3xx.h"
  41 
  42 /* global unit counter */
  43 static int i2c_id;
  44 
  45 static inline unsigned char
  46 iic_cook_addr(struct i2c_msg *msg)
  47 {
  48         unsigned char addr;
  49 
  50         addr = i2c_8bit_addr_from_msg(msg);
  51 
  52         return addr;
  53 }
  54 
  55 static void
  56 iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
  57 {
  58         /* Follows devman 9.3 */
  59         __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET);
  60         __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET);
  61         __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET);
  62 }
  63 
  64 static void
  65 iop3xx_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
  71          * on IOP3XX to avoid data corruption on the bus. We use the
  72          * gpiod_set_raw_value() to make sure the 0 hits the hardware
  73          * GPOD register. These descriptors are only passed along to
  74          * the device if this is necessary.
  75          */
  76         if (iop3xx_adap->gpio_scl)
  77                 gpiod_set_raw_value(iop3xx_adap->gpio_scl, 0);
  78         if (iop3xx_adap->gpio_sda)
  79                 gpiod_set_raw_value(iop3xx_adap->gpio_sda, 0);
  80 
  81         /* NB SR bits not same position as CR IE bits :-( */
  82         iop3xx_adap->SR_enabled =
  83                 IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD |
  84                 IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY;
  85 
  86         cr |= IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
  87                 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE;
  88 
  89         __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
  90 }
  91 
  92 static void
  93 iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
  94 {
  95         unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
  96 
  97         cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE |
  98                 IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN);
  99 
 100         __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 101 }
 102 
 103 /*
 104  * NB: the handler has to clear the source of the interrupt!
 105  * Then it passes the SR flags of interest to BH via adap data
 106  */
 107 static irqreturn_t
 108 iop3xx_i2c_irq_handler(int this_irq, void *dev_id)
 109 {
 110         struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
 111         u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET);
 112 
 113         if ((sr &= iop3xx_adap->SR_enabled)) {
 114                 __raw_writel(sr, iop3xx_adap->ioaddr + SR_OFFSET);
 115                 iop3xx_adap->SR_received |= sr;
 116                 wake_up_interruptible(&iop3xx_adap->waitq);
 117         }
 118         return IRQ_HANDLED;
 119 }
 120 
 121 /* check all error conditions, clear them , report most important */
 122 static int
 123 iop3xx_i2c_error(u32 sr)
 124 {
 125         int rc = 0;
 126 
 127         if ((sr & IOP3XX_ISR_BERRD)) {
 128                 if ( !rc ) rc = -I2C_ERR_BERR;
 129         }
 130         if ((sr & IOP3XX_ISR_ALD)) {
 131                 if ( !rc ) rc = -I2C_ERR_ALD;
 132         }
 133         return rc;
 134 }
 135 
 136 static inline u32
 137 iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
 138 {
 139         unsigned long flags;
 140         u32 sr;
 141 
 142         spin_lock_irqsave(&iop3xx_adap->lock, flags);
 143         sr = iop3xx_adap->SR_received;
 144         iop3xx_adap->SR_received = 0;
 145         spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
 146 
 147         return sr;
 148 }
 149 
 150 /*
 151  * sleep until interrupted, then recover and analyse the SR
 152  * saved by handler
 153  */
 154 typedef int (* compare_func)(unsigned test, unsigned mask);
 155 /* returns 1 on correct comparison */
 156 
 157 static int
 158 iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
 159                           unsigned flags, unsigned* status,
 160                           compare_func compare)
 161 {
 162         unsigned sr = 0;
 163         int interrupted;
 164         int done;
 165         int rc = 0;
 166 
 167         do {
 168                 interrupted = wait_event_interruptible_timeout (
 169                         iop3xx_adap->waitq,
 170                         (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
 171                         1 * HZ
 172                         );
 173                 if ((rc = iop3xx_i2c_error(sr)) < 0) {
 174                         *status = sr;
 175                         return rc;
 176                 } else if (!interrupted) {
 177                         *status = sr;
 178                         return -ETIMEDOUT;
 179                 }
 180         } while(!done);
 181 
 182         *status = sr;
 183 
 184         return 0;
 185 }
 186 
 187 /*
 188  * Concrete compare_funcs
 189  */
 190 static int
 191 all_bits_clear(unsigned test, unsigned mask)
 192 {
 193         return (test & mask) == 0;
 194 }
 195 
 196 static int
 197 any_bits_set(unsigned test, unsigned mask)
 198 {
 199         return (test & mask) != 0;
 200 }
 201 
 202 static int
 203 iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 204 {
 205         return iop3xx_i2c_wait_event(
 206                 iop3xx_adap,
 207                 IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
 208                 status, any_bits_set);
 209 }
 210 
 211 static int
 212 iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 213 {
 214         return iop3xx_i2c_wait_event(
 215                 iop3xx_adap,
 216                 IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD,
 217                 status, any_bits_set);
 218 }
 219 
 220 static int
 221 iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
 222 {
 223         return iop3xx_i2c_wait_event(
 224                 iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear);
 225 }
 226 
 227 static int
 228 iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
 229                                 struct i2c_msg* msg)
 230 {
 231         unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 232         int status;
 233         int rc;
 234 
 235         /* avoid writing to my slave address (hangs on 80331),
 236          * forbidden in Intel developer manual
 237          */
 238         if (msg->addr == MYSAR) {
 239                 return -EBUSY;
 240         }
 241 
 242         __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET);
 243 
 244         cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
 245         cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE;
 246 
 247         __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 248         rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
 249 
 250         return rc;
 251 }
 252 
 253 static int
 254 iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte,
 255                                 int stop)
 256 {
 257         unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 258         int status;
 259         int rc = 0;
 260 
 261         __raw_writel(byte, iop3xx_adap->ioaddr + DBR_OFFSET);
 262         cr &= ~IOP3XX_ICR_MSTART;
 263         if (stop) {
 264                 cr |= IOP3XX_ICR_MSTOP;
 265         } else {
 266                 cr &= ~IOP3XX_ICR_MSTOP;
 267         }
 268         cr |= IOP3XX_ICR_TBYTE;
 269         __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 270         rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status);
 271 
 272         return rc;
 273 }
 274 
 275 static int
 276 iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte,
 277                                 int stop)
 278 {
 279         unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET);
 280         int status;
 281         int rc = 0;
 282 
 283         cr &= ~IOP3XX_ICR_MSTART;
 284 
 285         if (stop) {
 286                 cr |= IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK;
 287         } else {
 288                 cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK);
 289         }
 290         cr |= IOP3XX_ICR_TBYTE;
 291         __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET);
 292 
 293         rc = iop3xx_i2c_wait_rx_done(iop3xx_adap, &status);
 294 
 295         *byte = __raw_readl(iop3xx_adap->ioaddr + DBR_OFFSET);
 296 
 297         return rc;
 298 }
 299 
 300 static int
 301 iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count)
 302 {
 303         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 304         int ii;
 305         int rc = 0;
 306 
 307         for (ii = 0; rc == 0 && ii != count; ++ii)
 308                 rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1);
 309         return rc;
 310 }
 311 
 312 static int
 313 iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count)
 314 {
 315         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 316         int ii;
 317         int rc = 0;
 318 
 319         for (ii = 0; rc == 0 && ii != count; ++ii)
 320                 rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1);
 321 
 322         return rc;
 323 }
 324 
 325 /*
 326  * Description:  This function implements combined transactions.  Combined
 327  * transactions consist of combinations of reading and writing blocks of data.
 328  * FROM THE SAME ADDRESS
 329  * Each transfer (i.e. a read or a write) is separated by a repeated start
 330  * condition.
 331  */
 332 static int
 333 iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg)
 334 {
 335         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 336         int rc;
 337 
 338         rc = iop3xx_i2c_send_target_addr(iop3xx_adap, pmsg);
 339         if (rc < 0) {
 340                 return rc;
 341         }
 342 
 343         if ((pmsg->flags&I2C_M_RD)) {
 344                 return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
 345         } else {
 346                 return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
 347         }
 348 }
 349 
 350 /*
 351  * master_xfer() - main read/write entry
 352  */
 353 static int
 354 iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
 355                                 int num)
 356 {
 357         struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
 358         int im = 0;
 359         int ret = 0;
 360         int status;
 361 
 362         iop3xx_i2c_wait_idle(iop3xx_adap, &status);
 363         iop3xx_i2c_reset(iop3xx_adap);
 364         iop3xx_i2c_enable(iop3xx_adap);
 365 
 366         for (im = 0; ret == 0 && im != num; im++) {
 367                 ret = iop3xx_i2c_handle_msg(i2c_adap, &msgs[im]);
 368         }
 369 
 370         iop3xx_i2c_transaction_cleanup(iop3xx_adap);
 371 
 372         if(ret)
 373                 return ret;
 374 
 375         return im;
 376 }
 377 
 378 static u32
 379 iop3xx_i2c_func(struct i2c_adapter *adap)
 380 {
 381         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 382 }
 383 
 384 static const struct i2c_algorithm iop3xx_i2c_algo = {
 385         .master_xfer    = iop3xx_i2c_master_xfer,
 386         .functionality  = iop3xx_i2c_func,
 387 };
 388 
 389 static int
 390 iop3xx_i2c_remove(struct platform_device *pdev)
 391 {
 392         struct i2c_adapter *padapter = platform_get_drvdata(pdev);
 393         struct i2c_algo_iop3xx_data *adapter_data =
 394                 (struct i2c_algo_iop3xx_data *)padapter->algo_data;
 395         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 396         unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET);
 397 
 398         /*
 399          * Disable the actual HW unit
 400          */
 401         cr &= ~(IOP3XX_ICR_ALD_IE | IOP3XX_ICR_BERR_IE |
 402                 IOP3XX_ICR_RXFULL_IE | IOP3XX_ICR_TXEMPTY_IE);
 403         __raw_writel(cr, adapter_data->ioaddr + CR_OFFSET);
 404 
 405         iounmap(adapter_data->ioaddr);
 406         release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
 407         kfree(adapter_data);
 408         kfree(padapter);
 409 
 410         return 0;
 411 }
 412 
 413 static int
 414 iop3xx_i2c_probe(struct platform_device *pdev)
 415 {
 416         struct resource *res;
 417         int ret, irq;
 418         struct i2c_adapter *new_adapter;
 419         struct i2c_algo_iop3xx_data *adapter_data;
 420 
 421         new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
 422         if (!new_adapter) {
 423                 ret = -ENOMEM;
 424                 goto out;
 425         }
 426 
 427         adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL);
 428         if (!adapter_data) {
 429                 ret = -ENOMEM;
 430                 goto free_adapter;
 431         }
 432 
 433         adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev,
 434                                                          "scl",
 435                                                          GPIOD_ASIS);
 436         if (IS_ERR(adapter_data->gpio_scl)) {
 437                 ret = PTR_ERR(adapter_data->gpio_scl);
 438                 goto free_both;
 439         }
 440         adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev,
 441                                                          "sda",
 442                                                          GPIOD_ASIS);
 443         if (IS_ERR(adapter_data->gpio_sda)) {
 444                 ret = PTR_ERR(adapter_data->gpio_sda);
 445                 goto free_both;
 446         }
 447 
 448         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 449         if (!res) {
 450                 ret = -ENODEV;
 451                 goto free_both;
 452         }
 453 
 454         if (!request_mem_region(res->start, IOP3XX_I2C_IO_SIZE, pdev->name)) {
 455                 ret = -EBUSY;
 456                 goto free_both;
 457         }
 458 
 459         /* set the adapter enumeration # */
 460         adapter_data->id = i2c_id++;
 461 
 462         adapter_data->ioaddr = ioremap(res->start, IOP3XX_I2C_IO_SIZE);
 463         if (!adapter_data->ioaddr) {
 464                 ret = -ENOMEM;
 465                 goto release_region;
 466         }
 467 
 468         irq = platform_get_irq(pdev, 0);
 469         if (irq < 0) {
 470                 ret = -ENXIO;
 471                 goto unmap;
 472         }
 473         ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
 474                                 pdev->name, adapter_data);
 475 
 476         if (ret) {
 477                 ret = -EIO;
 478                 goto unmap;
 479         }
 480 
 481         memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
 482         new_adapter->owner = THIS_MODULE;
 483         new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
 484         new_adapter->dev.parent = &pdev->dev;
 485         new_adapter->dev.of_node = pdev->dev.of_node;
 486         new_adapter->nr = pdev->id;
 487 
 488         /*
 489          * Default values...should these come in from board code?
 490          */
 491         new_adapter->timeout = HZ;
 492         new_adapter->algo = &iop3xx_i2c_algo;
 493 
 494         init_waitqueue_head(&adapter_data->waitq);
 495         spin_lock_init(&adapter_data->lock);
 496 
 497         iop3xx_i2c_reset(adapter_data);
 498         iop3xx_i2c_enable(adapter_data);
 499 
 500         platform_set_drvdata(pdev, new_adapter);
 501         new_adapter->algo_data = adapter_data;
 502 
 503         i2c_add_numbered_adapter(new_adapter);
 504 
 505         return 0;
 506 
 507 unmap:
 508         iounmap(adapter_data->ioaddr);
 509 
 510 release_region:
 511         release_mem_region(res->start, IOP3XX_I2C_IO_SIZE);
 512 
 513 free_both:
 514         kfree(adapter_data);
 515 
 516 free_adapter:
 517         kfree(new_adapter);
 518 
 519 out:
 520         return ret;
 521 }
 522 
 523 static const struct of_device_id i2c_iop3xx_match[] = {
 524         { .compatible = "intel,iop3xx-i2c", },
 525         { .compatible = "intel,ixp4xx-i2c", },
 526         {},
 527 };
 528 MODULE_DEVICE_TABLE(of, i2c_iop3xx_match);
 529 
 530 static struct platform_driver iop3xx_i2c_driver = {
 531         .probe          = iop3xx_i2c_probe,
 532         .remove         = iop3xx_i2c_remove,
 533         .driver         = {
 534                 .name   = "IOP3xx-I2C",
 535                 .of_match_table = i2c_iop3xx_match,
 536         },
 537 };
 538 
 539 module_platform_driver(iop3xx_i2c_driver);
 540 
 541 MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
 542 MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
 543 MODULE_LICENSE("GPL");
 544 MODULE_ALIAS("platform:IOP3xx-I2C");

/* [<][>][^][v][top][bottom][index][help] */