Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tps65912-core.c
Go to the documentation of this file.
1 /*
2  * tps65912-core.c -- TI TPS65912x
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/mfd/core.h>
22 #include <linux/mfd/tps65912.h>
23 
24 static struct mfd_cell tps65912s[] = {
25  {
26  .name = "tps65912-pmic",
27  },
28 };
29 
31 {
32  u8 data;
33  int err;
34 
35  mutex_lock(&tps65912->io_mutex);
36 
37  err = tps65912->read(tps65912, reg, 1, &data);
38  if (err) {
39  dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
40  goto out;
41  }
42 
43  data |= mask;
44  err = tps65912->write(tps65912, reg, 1, &data);
45  if (err)
46  dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
47 
48 out:
49  mutex_unlock(&tps65912->io_mutex);
50  return err;
51 }
53 
55 {
56  u8 data;
57  int err;
58 
59  mutex_lock(&tps65912->io_mutex);
60  err = tps65912->read(tps65912, reg, 1, &data);
61  if (err) {
62  dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
63  goto out;
64  }
65 
66  data &= ~mask;
67  err = tps65912->write(tps65912, reg, 1, &data);
68  if (err)
69  dev_err(tps65912->dev, "Write to reg 0x%x failed\n", reg);
70 
71 out:
72  mutex_unlock(&tps65912->io_mutex);
73  return err;
74 }
76 
77 static inline int tps65912_read(struct tps65912 *tps65912, u8 reg)
78 {
79  u8 val;
80  int err;
81 
82  err = tps65912->read(tps65912, reg, 1, &val);
83  if (err < 0)
84  return err;
85 
86  return val;
87 }
88 
89 static inline int tps65912_write(struct tps65912 *tps65912, u8 reg, u8 val)
90 {
91  return tps65912->write(tps65912, reg, 1, &val);
92 }
93 
94 int tps65912_reg_read(struct tps65912 *tps65912, u8 reg)
95 {
96  int data;
97 
98  mutex_lock(&tps65912->io_mutex);
99 
100  data = tps65912_read(tps65912, reg);
101  if (data < 0)
102  dev_err(tps65912->dev, "Read from reg 0x%x failed\n", reg);
103 
104  mutex_unlock(&tps65912->io_mutex);
105  return data;
106 }
108 
109 int tps65912_reg_write(struct tps65912 *tps65912, u8 reg, u8 val)
110 {
111  int err;
112 
113  mutex_lock(&tps65912->io_mutex);
114 
115  err = tps65912_write(tps65912, reg, val);
116  if (err < 0)
117  dev_err(tps65912->dev, "Write for reg 0x%x failed\n", reg);
118 
119  mutex_unlock(&tps65912->io_mutex);
120  return err;
121 }
123 
124 int tps65912_device_init(struct tps65912 *tps65912)
125 {
126  struct tps65912_board *pmic_plat_data = tps65912->dev->platform_data;
127  struct tps65912_platform_data *init_data;
128  int ret, dcdc_avs, value;
129 
130  init_data = kzalloc(sizeof(struct tps65912_platform_data), GFP_KERNEL);
131  if (init_data == NULL)
132  return -ENOMEM;
133 
134  mutex_init(&tps65912->io_mutex);
135  dev_set_drvdata(tps65912->dev, tps65912);
136 
137  dcdc_avs = (pmic_plat_data->is_dcdc1_avs << 0 |
138  pmic_plat_data->is_dcdc2_avs << 1 |
139  pmic_plat_data->is_dcdc3_avs << 2 |
140  pmic_plat_data->is_dcdc4_avs << 3);
141  if (dcdc_avs) {
142  tps65912->read(tps65912, TPS65912_I2C_SPI_CFG, 1, &value);
143  dcdc_avs |= value;
144  tps65912->write(tps65912, TPS65912_I2C_SPI_CFG, 1, &dcdc_avs);
145  }
146 
147  ret = mfd_add_devices(tps65912->dev, -1,
148  tps65912s, ARRAY_SIZE(tps65912s),
149  NULL, 0, NULL);
150  if (ret < 0)
151  goto err;
152 
153  init_data->irq = pmic_plat_data->irq;
154  init_data->irq_base = pmic_plat_data->irq_base;
155  ret = tps65912_irq_init(tps65912, init_data->irq, init_data);
156  if (ret < 0)
157  goto err;
158 
159  kfree(init_data);
160  return ret;
161 
162 err:
163  kfree(init_data);
164  mfd_remove_devices(tps65912->dev);
165  kfree(tps65912);
166  return ret;
167 }
168 
169 void tps65912_device_exit(struct tps65912 *tps65912)
170 {
171  mfd_remove_devices(tps65912->dev);
172  kfree(tps65912);
173 }
174 
175 MODULE_AUTHOR("Margarita Olaya <[email protected]>");
176 MODULE_DESCRIPTION("TPS65912x chip family multi-function driver");
177 MODULE_LICENSE("GPL");