i2c-acorn.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * ARM IOC/IOMD i2c driver.
  3. *
  4. * Copyright (C) 2000 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * On Acorn machines, the following i2c devices are on the bus:
  11. * - PCF8583 real time clock & static RAM
  12. */
  13. #include <linux/module.h>
  14. #include <linux/i2c.h>
  15. #include <linux/i2c-algo-bit.h>
  16. #include <linux/io.h>
  17. #include <mach/hardware.h>
  18. #include <asm/hardware/ioc.h>
  19. #define FORCE_ONES 0xdc
  20. #define SCL 0x02
  21. #define SDA 0x01
  22. /*
  23. * We must preserve all non-i2c output bits in IOC_CONTROL.
  24. * Note also that we need to preserve the value of SCL and
  25. * SDA outputs as well (which may be different from the
  26. * values read back from IOC_CONTROL).
  27. */
  28. static u_int force_ones;
  29. static void ioc_setscl(void *data, int state)
  30. {
  31. u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
  32. u_int ones = force_ones;
  33. if (state)
  34. ones |= SCL;
  35. else
  36. ones &= ~SCL;
  37. force_ones = ones;
  38. ioc_writeb(ioc_control | ones, IOC_CONTROL);
  39. }
  40. static void ioc_setsda(void *data, int state)
  41. {
  42. u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA);
  43. u_int ones = force_ones;
  44. if (state)
  45. ones |= SDA;
  46. else
  47. ones &= ~SDA;
  48. force_ones = ones;
  49. ioc_writeb(ioc_control | ones, IOC_CONTROL);
  50. }
  51. static int ioc_getscl(void *data)
  52. {
  53. return (ioc_readb(IOC_CONTROL) & SCL) != 0;
  54. }
  55. static int ioc_getsda(void *data)
  56. {
  57. return (ioc_readb(IOC_CONTROL) & SDA) != 0;
  58. }
  59. static struct i2c_algo_bit_data ioc_data = {
  60. .setsda = ioc_setsda,
  61. .setscl = ioc_setscl,
  62. .getsda = ioc_getsda,
  63. .getscl = ioc_getscl,
  64. .udelay = 80,
  65. .timeout = HZ,
  66. };
  67. static struct i2c_adapter ioc_ops = {
  68. .nr = 0,
  69. .name = "ioc",
  70. .algo_data = &ioc_data,
  71. };
  72. static int __init i2c_ioc_init(void)
  73. {
  74. force_ones = FORCE_ONES | SCL | SDA;
  75. return i2c_bit_add_numbered_bus(&ioc_ops);
  76. }
  77. module_init(i2c_ioc_init);
  78. MODULE_AUTHOR("Russell King <linux@armlinux.org.uk>");
  79. MODULE_DESCRIPTION("ARM IOC/IOMD i2c driver");
  80. MODULE_LICENSE("GPL v2");