]>
Commit | Line | Data |
---|---|---|
36e52873 MO |
1 | /* |
2 | * tps65912-spi.c -- SPI access for TI TPS65912x PMIC | |
3 | * | |
4 | * Copyright 2011 Texas Instruments Inc. | |
5 | * | |
6 | * Author: Margarita Olaya Cabrera <[email protected]> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2 of the License, or (at your | |
11 | * option) any later version. | |
12 | * | |
13 | * This driver is based on wm8350 implementation. | |
14 | */ | |
15 | ||
16 | #include <linux/module.h> | |
17 | #include <linux/moduleparam.h> | |
18 | #include <linux/init.h> | |
19 | #include <linux/slab.h> | |
20 | #include <linux/gpio.h> | |
21 | #include <linux/spi/spi.h> | |
22 | #include <linux/mfd/core.h> | |
23 | #include <linux/mfd/tps65912.h> | |
24 | ||
25 | static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr, | |
26 | int bytes, void *src) | |
27 | { | |
28 | struct spi_device *spi = tps65912->control_data; | |
29 | u8 *data = (u8 *) src; | |
30 | int ret; | |
31 | /* bit 23 is the read/write bit */ | |
32 | unsigned long spi_data = 1 << 23 | addr << 15 | *data; | |
33 | struct spi_transfer xfer; | |
34 | struct spi_message msg; | |
35 | u32 tx_buf, rx_buf; | |
36 | ||
37 | tx_buf = spi_data; | |
38 | rx_buf = 0; | |
39 | ||
40 | xfer.tx_buf = &tx_buf; | |
41 | xfer.rx_buf = NULL; | |
42 | xfer.len = sizeof(unsigned long); | |
43 | xfer.bits_per_word = 24; | |
44 | ||
45 | spi_message_init(&msg); | |
46 | spi_message_add_tail(&xfer, &msg); | |
47 | ||
48 | ret = spi_sync(spi, &msg); | |
49 | return ret; | |
50 | } | |
51 | ||
52 | static int tps65912_spi_read(struct tps65912 *tps65912, u8 addr, | |
53 | int bytes, void *dest) | |
54 | { | |
55 | struct spi_device *spi = tps65912->control_data; | |
56 | /* bit 23 is the read/write bit */ | |
57 | unsigned long spi_data = 0 << 23 | addr << 15; | |
58 | struct spi_transfer xfer; | |
59 | struct spi_message msg; | |
60 | int ret; | |
61 | u8 *data = (u8 *) dest; | |
62 | u32 tx_buf, rx_buf; | |
63 | ||
64 | tx_buf = spi_data; | |
65 | rx_buf = 0; | |
66 | ||
67 | xfer.tx_buf = &tx_buf; | |
68 | xfer.rx_buf = &rx_buf; | |
69 | xfer.len = sizeof(unsigned long); | |
70 | xfer.bits_per_word = 24; | |
71 | ||
72 | spi_message_init(&msg); | |
73 | spi_message_add_tail(&xfer, &msg); | |
74 | ||
75 | if (spi == NULL) | |
76 | return 0; | |
77 | ||
78 | ret = spi_sync(spi, &msg); | |
79 | if (ret == 0) | |
80 | *data = (u8) (rx_buf & 0xFF); | |
81 | return ret; | |
82 | } | |
83 | ||
84 | static int __devinit tps65912_spi_probe(struct spi_device *spi) | |
85 | { | |
86 | struct tps65912 *tps65912; | |
87 | ||
88 | tps65912 = kzalloc(sizeof(struct tps65912), GFP_KERNEL); | |
89 | if (tps65912 == NULL) | |
90 | return -ENOMEM; | |
91 | ||
92 | tps65912->dev = &spi->dev; | |
93 | tps65912->control_data = spi; | |
94 | tps65912->read = tps65912_spi_read; | |
95 | tps65912->write = tps65912_spi_write; | |
96 | ||
97 | spi_set_drvdata(spi, tps65912); | |
98 | ||
99 | return tps65912_device_init(tps65912); | |
100 | } | |
101 | ||
102 | static int __devexit tps65912_spi_remove(struct spi_device *spi) | |
103 | { | |
104 | struct tps65912 *tps65912 = spi_get_drvdata(spi); | |
105 | ||
106 | tps65912_device_exit(tps65912); | |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
111 | static struct spi_driver tps65912_spi_driver = { | |
112 | .driver = { | |
113 | .name = "tps65912", | |
36e52873 MO |
114 | .owner = THIS_MODULE, |
115 | }, | |
116 | .probe = tps65912_spi_probe, | |
117 | .remove = __devexit_p(tps65912_spi_remove), | |
118 | }; | |
119 | ||
120 | static int __init tps65912_spi_init(void) | |
121 | { | |
122 | int ret; | |
123 | ||
124 | ret = spi_register_driver(&tps65912_spi_driver); | |
125 | if (ret != 0) | |
126 | pr_err("Failed to register TPS65912 SPI driver: %d\n", ret); | |
127 | ||
128 | return 0; | |
129 | } | |
130 | /* init early so consumer devices can complete system boot */ | |
131 | subsys_initcall(tps65912_spi_init); | |
132 | ||
133 | static void __exit tps65912_spi_exit(void) | |
134 | { | |
135 | spi_unregister_driver(&tps65912_spi_driver); | |
136 | } | |
137 | module_exit(tps65912_spi_exit); | |
138 | ||
139 | MODULE_AUTHOR("Margarita Olaya <[email protected]>"); | |
140 | MODULE_DESCRIPTION("SPI support for TPS65912 chip family mfd"); | |
141 | MODULE_LICENSE("GPL"); |