max8925-i2c.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * I2C driver for Maxim MAX8925
  3. *
  4. * Copyright (C) 2009 Marvell International Ltd.
  5. * Haojian Zhuang <haojian.zhuang@marvell.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/i2c.h>
  15. #include <linux/mfd/max8925.h>
  16. #define RTC_I2C_ADDR 0x68
  17. #define ADC_I2C_ADDR 0x47
  18. static inline int max8925_read_device(struct i2c_client *i2c,
  19. int reg, int bytes, void *dest)
  20. {
  21. int ret;
  22. if (bytes > 1)
  23. ret = i2c_smbus_read_i2c_block_data(i2c, reg, bytes, dest);
  24. else {
  25. ret = i2c_smbus_read_byte_data(i2c, reg);
  26. if (ret < 0)
  27. return ret;
  28. *(unsigned char *)dest = (unsigned char)ret;
  29. }
  30. return ret;
  31. }
  32. static inline int max8925_write_device(struct i2c_client *i2c,
  33. int reg, int bytes, void *src)
  34. {
  35. unsigned char buf[bytes + 1];
  36. int ret;
  37. buf[0] = (unsigned char)reg;
  38. memcpy(&buf[1], src, bytes);
  39. ret = i2c_master_send(i2c, buf, bytes + 1);
  40. if (ret < 0)
  41. return ret;
  42. return 0;
  43. }
  44. int max8925_reg_read(struct i2c_client *i2c, int reg)
  45. {
  46. struct max8925_chip *chip = i2c_get_clientdata(i2c);
  47. unsigned char data = 0;
  48. int ret;
  49. mutex_lock(&chip->io_lock);
  50. ret = max8925_read_device(i2c, reg, 1, &data);
  51. mutex_unlock(&chip->io_lock);
  52. if (ret < 0)
  53. return ret;
  54. else
  55. return (int)data;
  56. }
  57. EXPORT_SYMBOL(max8925_reg_read);
  58. int max8925_reg_write(struct i2c_client *i2c, int reg,
  59. unsigned char data)
  60. {
  61. struct max8925_chip *chip = i2c_get_clientdata(i2c);
  62. int ret;
  63. mutex_lock(&chip->io_lock);
  64. ret = max8925_write_device(i2c, reg, 1, &data);
  65. mutex_unlock(&chip->io_lock);
  66. return ret;
  67. }
  68. EXPORT_SYMBOL(max8925_reg_write);
  69. int max8925_bulk_read(struct i2c_client *i2c, int reg,
  70. int count, unsigned char *buf)
  71. {
  72. struct max8925_chip *chip = i2c_get_clientdata(i2c);
  73. int ret;
  74. mutex_lock(&chip->io_lock);
  75. ret = max8925_read_device(i2c, reg, count, buf);
  76. mutex_unlock(&chip->io_lock);
  77. return ret;
  78. }
  79. EXPORT_SYMBOL(max8925_bulk_read);
  80. int max8925_bulk_write(struct i2c_client *i2c, int reg,
  81. int count, unsigned char *buf)
  82. {
  83. struct max8925_chip *chip = i2c_get_clientdata(i2c);
  84. int ret;
  85. mutex_lock(&chip->io_lock);
  86. ret = max8925_write_device(i2c, reg, count, buf);
  87. mutex_unlock(&chip->io_lock);
  88. return ret;
  89. }
  90. EXPORT_SYMBOL(max8925_bulk_write);
  91. int max8925_set_bits(struct i2c_client *i2c, int reg,
  92. unsigned char mask, unsigned char data)
  93. {
  94. struct max8925_chip *chip = i2c_get_clientdata(i2c);
  95. unsigned char value;
  96. int ret;
  97. mutex_lock(&chip->io_lock);
  98. ret = max8925_read_device(i2c, reg, 1, &value);
  99. if (ret < 0)
  100. goto out;
  101. value &= ~mask;
  102. value |= data;
  103. ret = max8925_write_device(i2c, reg, 1, &value);
  104. out:
  105. mutex_unlock(&chip->io_lock);
  106. return ret;
  107. }
  108. EXPORT_SYMBOL(max8925_set_bits);
  109. static const struct i2c_device_id max8925_id_table[] = {
  110. { "max8925", 0 },
  111. { },
  112. };
  113. MODULE_DEVICE_TABLE(i2c, max8925_id_table);
  114. static int __devinit max8925_probe(struct i2c_client *client,
  115. const struct i2c_device_id *id)
  116. {
  117. struct max8925_platform_data *pdata = client->dev.platform_data;
  118. static struct max8925_chip *chip;
  119. if (!pdata) {
  120. pr_info("%s: platform data is missing\n", __func__);
  121. return -EINVAL;
  122. }
  123. chip = kzalloc(sizeof(struct max8925_chip), GFP_KERNEL);
  124. if (chip == NULL)
  125. return -ENOMEM;
  126. chip->i2c = client;
  127. chip->dev = &client->dev;
  128. i2c_set_clientdata(client, chip);
  129. dev_set_drvdata(chip->dev, chip);
  130. mutex_init(&chip->io_lock);
  131. chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR);
  132. i2c_set_clientdata(chip->rtc, chip);
  133. chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
  134. i2c_set_clientdata(chip->adc, chip);
  135. max8925_device_init(chip, pdata);
  136. return 0;
  137. }
  138. static int __devexit max8925_remove(struct i2c_client *client)
  139. {
  140. struct max8925_chip *chip = i2c_get_clientdata(client);
  141. max8925_device_exit(chip);
  142. i2c_unregister_device(chip->adc);
  143. i2c_unregister_device(chip->rtc);
  144. i2c_set_clientdata(chip->adc, NULL);
  145. i2c_set_clientdata(chip->rtc, NULL);
  146. i2c_set_clientdata(chip->i2c, NULL);
  147. kfree(chip);
  148. return 0;
  149. }
  150. static struct i2c_driver max8925_driver = {
  151. .driver = {
  152. .name = "max8925",
  153. .owner = THIS_MODULE,
  154. },
  155. .probe = max8925_probe,
  156. .remove = __devexit_p(max8925_remove),
  157. .id_table = max8925_id_table,
  158. };
  159. static int __init max8925_i2c_init(void)
  160. {
  161. int ret;
  162. ret = i2c_add_driver(&max8925_driver);
  163. if (ret != 0)
  164. pr_err("Failed to register MAX8925 I2C driver: %d\n", ret);
  165. return ret;
  166. }
  167. subsys_initcall(max8925_i2c_init);
  168. static void __exit max8925_i2c_exit(void)
  169. {
  170. i2c_del_driver(&max8925_driver);
  171. }
  172. module_exit(max8925_i2c_exit);
  173. MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
  174. MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
  175. MODULE_LICENSE("GPL");