board-mop500-uib.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
  5. * License terms: GNU General Public License (GPL), version 2
  6. */
  7. #define pr_fmt(fmt) "mop500-uib: " fmt
  8. #include <linux/kernel.h>
  9. #include <linux/init.h>
  10. #include <linux/i2c.h>
  11. #include <mach/hardware.h>
  12. #include "board-mop500.h"
  13. enum mop500_uib {
  14. STUIB,
  15. U8500UIB,
  16. };
  17. struct uib {
  18. const char *name;
  19. const char *option;
  20. void (*init)(void);
  21. };
  22. static struct __initdata uib mop500_uibs[] = {
  23. [STUIB] = {
  24. .name = "ST-UIB",
  25. .option = "stuib",
  26. .init = mop500_stuib_init,
  27. },
  28. [U8500UIB] = {
  29. .name = "U8500-UIB",
  30. .option = "u8500uib",
  31. .init = mop500_u8500uib_init,
  32. },
  33. };
  34. static struct uib *mop500_uib;
  35. static int __init mop500_uib_setup(char *str)
  36. {
  37. int i;
  38. for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) {
  39. struct uib *uib = &mop500_uibs[i];
  40. if (!strcmp(str, uib->option)) {
  41. mop500_uib = uib;
  42. break;
  43. }
  44. }
  45. if (i == ARRAY_SIZE(mop500_uibs))
  46. pr_err("invalid uib= option (%s)\n", str);
  47. return 1;
  48. }
  49. __setup("uib=", mop500_uib_setup);
  50. /*
  51. * The UIBs are detected after the I2C host controllers are registered, so
  52. * i2c_register_board_info() can't be used.
  53. */
  54. void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
  55. unsigned n)
  56. {
  57. struct i2c_adapter *adap;
  58. struct i2c_client *client;
  59. int i;
  60. adap = i2c_get_adapter(busnum);
  61. if (!adap) {
  62. pr_err("failed to get adapter i2c%d\n", busnum);
  63. return;
  64. }
  65. for (i = 0; i < n; i++) {
  66. client = i2c_new_device(adap, &info[i]);
  67. if (!client)
  68. pr_err("failed to register %s to i2c%d\n",
  69. info[i].type, busnum);
  70. }
  71. i2c_put_adapter(adap);
  72. }
  73. static void __init __mop500_uib_init(struct uib *uib, const char *why)
  74. {
  75. pr_info("%s (%s)\n", uib->name, why);
  76. uib->init();
  77. }
  78. /*
  79. * Detect the UIB attached based on the presence or absence of i2c devices.
  80. */
  81. static int __init mop500_uib_init(void)
  82. {
  83. struct uib *uib = mop500_uib;
  84. struct i2c_adapter *i2c0;
  85. int ret;
  86. if (!cpu_is_u8500())
  87. return -ENODEV;
  88. if (uib) {
  89. __mop500_uib_init(uib, "from uib= boot argument");
  90. return 0;
  91. }
  92. i2c0 = i2c_get_adapter(0);
  93. if (!i2c0) {
  94. __mop500_uib_init(&mop500_uibs[STUIB],
  95. "fallback, could not get i2c0");
  96. return -ENODEV;
  97. }
  98. /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */
  99. ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0,
  100. I2C_SMBUS_QUICK, NULL);
  101. i2c_put_adapter(i2c0);
  102. if (ret == 0)
  103. uib = &mop500_uibs[U8500UIB];
  104. else
  105. uib = &mop500_uibs[STUIB];
  106. __mop500_uib_init(uib, "detected");
  107. return 0;
  108. }
  109. module_init(mop500_uib_init);