ab4500-core.c 4.9 KB

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