ab4500-core.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (C) 2009 ST-Ericsson
  3. *
  4. * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
  5. *
  6. * This program is free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation.
  9. *
  10. * AB4500 is a companion power management chip used with U8500.
  11. * On this platform, this is interfaced with SSP0 controller
  12. * which is a ARM primecell pl022.
  13. *
  14. * At the moment the module just exports read/write features.
  15. * Interrupt management to be added - TODO.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/init.h>
  19. #include <linux/module.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/spi/spi.h>
  22. #include <linux/mfd/ab4500.h>
  23. /* just required if probe fails, we need to
  24. * unregister the device
  25. */
  26. static struct spi_driver ab4500_driver;
  27. /*
  28. * This funtion writes to any AB4500 registers using
  29. * SPI protocol & before it writes it packs the data
  30. * in the below 24 bit frame format
  31. *
  32. * *|------------------------------------|
  33. * *| 23|22...18|17.......10|9|8|7......0|
  34. * *| r/w bank adr data |
  35. * * ------------------------------------
  36. *
  37. * This function shouldn't be called from interrupt
  38. * context
  39. */
  40. int ab4500_write(struct ab4500 *ab4500, unsigned char block,
  41. unsigned long addr, unsigned char data)
  42. {
  43. struct spi_transfer xfer;
  44. struct spi_message msg;
  45. int err;
  46. unsigned long spi_data =
  47. block << 18 | addr << 10 | data;
  48. mutex_lock(&ab4500->lock);
  49. ab4500->tx_buf[0] = spi_data;
  50. ab4500->rx_buf[0] = 0;
  51. xfer.tx_buf = ab4500->tx_buf;
  52. xfer.rx_buf = NULL;
  53. xfer.len = sizeof(unsigned long);
  54. spi_message_init(&msg);
  55. spi_message_add_tail(&xfer, &msg);
  56. err = spi_sync(ab4500->spi, &msg);
  57. mutex_unlock(&ab4500->lock);
  58. return err;
  59. }
  60. EXPORT_SYMBOL(ab4500_write);
  61. int ab4500_read(struct ab4500 *ab4500, unsigned char block,
  62. unsigned long addr)
  63. {
  64. struct spi_transfer xfer;
  65. struct spi_message msg;
  66. unsigned long spi_data =
  67. 1 << 23 | block << 18 | addr << 10;
  68. mutex_lock(&ab4500->lock);
  69. ab4500->tx_buf[0] = spi_data;
  70. ab4500->rx_buf[0] = 0;
  71. xfer.tx_buf = ab4500->tx_buf;
  72. xfer.rx_buf = ab4500->rx_buf;
  73. xfer.len = sizeof(unsigned long);
  74. spi_message_init(&msg);
  75. spi_message_add_tail(&xfer, &msg);
  76. spi_sync(ab4500->spi, &msg);
  77. mutex_unlock(&ab4500->lock);
  78. return ab4500->rx_buf[0];
  79. }
  80. EXPORT_SYMBOL(ab4500_read);
  81. /* ref: ab3100 core */
  82. #define AB4500_DEVICE(devname, devid) \
  83. static struct platform_device ab4500_##devname##_device = { \
  84. .name = devid, \
  85. .id = -1, \
  86. }
  87. /* list of childern devices of ab4500 - all are
  88. * not populated here - TODO
  89. */
  90. AB4500_DEVICE(charger, "ab4500-charger");
  91. AB4500_DEVICE(audio, "ab4500-audio");
  92. AB4500_DEVICE(usb, "ab4500-usb");
  93. AB4500_DEVICE(tvout, "ab4500-tvout");
  94. AB4500_DEVICE(sim, "ab4500-sim");
  95. AB4500_DEVICE(gpadc, "ab4500-gpadc");
  96. AB4500_DEVICE(clkmgt, "ab4500-clkmgt");
  97. AB4500_DEVICE(misc, "ab4500-misc");
  98. static struct platform_device *ab4500_platform_devs[] = {
  99. &ab4500_charger_device,
  100. &ab4500_audio_device,
  101. &ab4500_usb_device,
  102. &ab4500_tvout_device,
  103. &ab4500_sim_device,
  104. &ab4500_gpadc_device,
  105. &ab4500_clkmgt_device,
  106. &ab4500_misc_device,
  107. };
  108. static int __init ab4500_probe(struct spi_device *spi)
  109. {
  110. struct ab4500 *ab4500;
  111. unsigned char revision;
  112. int err = 0;
  113. int i;
  114. ab4500 = kzalloc(sizeof *ab4500, GFP_KERNEL);
  115. if (!ab4500) {
  116. dev_err(&spi->dev, "could not allocate AB4500\n");
  117. err = -ENOMEM;
  118. goto not_detect;
  119. }
  120. ab4500->spi = spi;
  121. spi_set_drvdata(spi, ab4500);
  122. mutex_init(&ab4500->lock);
  123. /* read the revision register */
  124. revision = ab4500_read(ab4500, AB4500_MISC, AB4500_REV_REG);
  125. /* revision id 0x0 is for early drop, 0x10 is for cut1.0 */
  126. if (revision == 0x0 || revision == 0x10)
  127. dev_info(&spi->dev, "Detected chip: %s, revision = %x\n",
  128. ab4500_driver.driver.name, revision);
  129. else {
  130. dev_err(&spi->dev, "unknown chip: 0x%x\n", revision);
  131. goto not_detect;
  132. }
  133. for (i = 0; i < ARRAY_SIZE(ab4500_platform_devs); i++) {
  134. ab4500_platform_devs[i]->dev.parent =
  135. &spi->dev;
  136. platform_set_drvdata(ab4500_platform_devs[i], ab4500);
  137. }
  138. /* register the ab4500 platform devices */
  139. platform_add_devices(ab4500_platform_devs,
  140. ARRAY_SIZE(ab4500_platform_devs));
  141. return err;
  142. not_detect:
  143. spi_unregister_driver(&ab4500_driver);
  144. kfree(ab4500);
  145. return err;
  146. }
  147. static int __devexit ab4500_remove(struct spi_device *spi)
  148. {
  149. struct ab4500 *ab4500 =
  150. spi_get_drvdata(spi);
  151. kfree(ab4500);
  152. return 0;
  153. }
  154. static struct spi_driver ab4500_driver = {
  155. .driver = {
  156. .name = "ab4500",
  157. .owner = THIS_MODULE,
  158. },
  159. .probe = ab4500_probe,
  160. .remove = __devexit_p(ab4500_remove)
  161. };
  162. static int __devinit ab4500_init(void)
  163. {
  164. return spi_register_driver(&ab4500_driver);
  165. }
  166. static void __exit ab4500_exit(void)
  167. {
  168. spi_unregister_driver(&ab4500_driver);
  169. }
  170. subsys_initcall(ab4500_init);
  171. module_exit(ab4500_exit);
  172. MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com");
  173. MODULE_DESCRIPTION("AB4500 core driver");
  174. MODULE_LICENSE("GPL");