aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2016-08-31 03:49:46 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2016-09-22 04:39:02 -0400
commitac61b6001a636ab9aa954b5f9a996056cd8519f4 (patch)
treed2c5e8c5344232f0dc781c68b23f0cdbb3375408
parenta1d0500261e788f9b1d068e3167b2a77ad0abfc4 (diff)
pcmcia: soc_common: add support for Vcc and Vpp regulators
Add support for handling supply regulators in the soc_common code. This allows us to separate out the board specifics for setting voltages from the PCMCIA code. We detect when setting a voltage fails, and report this fact - some platforms have fixed-voltage supplies (eg, for CF sockets at 3.3V) and we need to ignore attempts to configure for 5V, as per the existing board specific drivers. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--drivers/pcmcia/soc_common.c37
-rw-r--r--drivers/pcmcia/soc_common.h11
2 files changed, 47 insertions, 1 deletions
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 6d0ec291f475..15e332aca0f3 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/moduleparam.h> 44#include <linux/moduleparam.h>
45#include <linux/mutex.h> 45#include <linux/mutex.h>
46#include <linux/regulator/consumer.h>
46#include <linux/spinlock.h> 47#include <linux/spinlock.h>
47#include <linux/timer.h> 48#include <linux/timer.h>
48 49
@@ -80,6 +81,41 @@ EXPORT_SYMBOL(soc_pcmcia_debug);
80#define to_soc_pcmcia_socket(x) \ 81#define to_soc_pcmcia_socket(x) \
81 container_of(x, struct soc_pcmcia_socket, socket) 82 container_of(x, struct soc_pcmcia_socket, socket)
82 83
84int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
85 struct soc_pcmcia_regulator *r, int v)
86{
87 bool on;
88 int ret;
89
90 if (!r->reg)
91 return 0;
92
93 on = v != 0;
94 if (r->on == on)
95 return 0;
96
97 if (on) {
98 ret = regulator_set_voltage(r->reg, v * 100000, v * 100000);
99 if (ret) {
100 int vout = regulator_get_voltage(r->reg) / 100000;
101
102 dev_warn(&skt->socket.dev,
103 "CS requested %s=%u.%uV, applying %u.%uV\n",
104 r == &skt->vcc ? "Vcc" : "Vpp",
105 v / 10, v % 10, vout / 10, vout % 10);
106 }
107
108 ret = regulator_enable(r->reg);
109 } else {
110 regulator_disable(r->reg);
111 }
112 if (ret == 0)
113 r->on = on;
114
115 return ret;
116}
117EXPORT_SYMBOL_GPL(soc_pcmcia_regulator_set);
118
83static unsigned short 119static unsigned short
84calc_speed(unsigned short *spds, int num, unsigned short dflt) 120calc_speed(unsigned short *spds, int num, unsigned short dflt)
85{ 121{
@@ -119,7 +155,6 @@ static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
119 if (skt->ops->hw_shutdown) 155 if (skt->ops->hw_shutdown)
120 skt->ops->hw_shutdown(skt); 156 skt->ops->hw_shutdown(skt);
121 157
122
123 clk_disable_unprepare(skt->clk); 158 clk_disable_unprepare(skt->clk);
124} 159}
125 160
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 39c1e15167f3..18a6df5ca374 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -19,6 +19,12 @@
19struct device; 19struct device;
20struct gpio_desc; 20struct gpio_desc;
21struct pcmcia_low_level; 21struct pcmcia_low_level;
22struct regulator;
23
24struct soc_pcmcia_regulator {
25 struct regulator *reg;
26 bool on;
27};
22 28
23/* 29/*
24 * This structure encapsulates per-socket state which we might need to 30 * This structure encapsulates per-socket state which we might need to
@@ -64,6 +70,8 @@ struct soc_pcmcia_socket {
64 70
65 struct gpio_desc *gpio_reset; 71 struct gpio_desc *gpio_reset;
66 struct gpio_desc *gpio_bus_enable; 72 struct gpio_desc *gpio_bus_enable;
73 struct soc_pcmcia_regulator vcc;
74 struct soc_pcmcia_regulator vpp;
67 75
68 unsigned int irq_state; 76 unsigned int irq_state;
69 77
@@ -146,6 +154,9 @@ int soc_pcmcia_request_gpiods(struct soc_pcmcia_socket *skt);
146void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt, 154void soc_common_cf_socket_state(struct soc_pcmcia_socket *skt,
147 struct pcmcia_state *state); 155 struct pcmcia_state *state);
148 156
157int soc_pcmcia_regulator_set(struct soc_pcmcia_socket *skt,
158 struct soc_pcmcia_regulator *r, int v);
159
149#ifdef CONFIG_PCMCIA_DEBUG 160#ifdef CONFIG_PCMCIA_DEBUG
150 161
151extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func, 162extern void soc_pcmcia_debug(struct soc_pcmcia_socket *skt, const char *func,