xref: /openbmc/linux/drivers/mfd/mcp-sa11x0.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   *  linux/drivers/mfd/mcp-sa11x0.c
4   *
5   *  Copyright (C) 2001-2005 Russell King
6   *
7   *  SA11x0 MCP (Multimedia Communications Port) driver.
8   *
9   *  MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
10   */
11  #include <linux/module.h>
12  #include <linux/io.h>
13  #include <linux/errno.h>
14  #include <linux/kernel.h>
15  #include <linux/delay.h>
16  #include <linux/spinlock.h>
17  #include <linux/platform_device.h>
18  #include <linux/pm.h>
19  #include <linux/mfd/mcp.h>
20  
21  #include <mach/hardware.h>
22  #include <asm/mach-types.h>
23  #include <linux/platform_data/mfd-mcp-sa11x0.h>
24  
25  #define DRIVER_NAME "sa11x0-mcp"
26  
27  struct mcp_sa11x0 {
28  	void __iomem	*base0;
29  	void __iomem	*base1;
30  	u32		mccr0;
31  	u32		mccr1;
32  };
33  
34  /* Register offsets */
35  #define MCCR0(m)	((m)->base0 + 0x00)
36  #define MCDR0(m)	((m)->base0 + 0x08)
37  #define MCDR1(m)	((m)->base0 + 0x0c)
38  #define MCDR2(m)	((m)->base0 + 0x10)
39  #define MCSR(m)		((m)->base0 + 0x18)
40  #define MCCR1(m)	((m)->base1 + 0x00)
41  
42  #define priv(mcp)	((struct mcp_sa11x0 *)mcp_priv(mcp))
43  
44  static void
mcp_sa11x0_set_telecom_divisor(struct mcp * mcp,unsigned int divisor)45  mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
46  {
47  	struct mcp_sa11x0 *m = priv(mcp);
48  
49  	divisor /= 32;
50  
51  	m->mccr0 &= ~0x00007f00;
52  	m->mccr0 |= divisor << 8;
53  	writel_relaxed(m->mccr0, MCCR0(m));
54  }
55  
56  static void
mcp_sa11x0_set_audio_divisor(struct mcp * mcp,unsigned int divisor)57  mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
58  {
59  	struct mcp_sa11x0 *m = priv(mcp);
60  
61  	divisor /= 32;
62  
63  	m->mccr0 &= ~0x0000007f;
64  	m->mccr0 |= divisor;
65  	writel_relaxed(m->mccr0, MCCR0(m));
66  }
67  
68  /*
69   * Write data to the device.  The bit should be set after 3 subframe
70   * times (each frame is 64 clocks).  We wait a maximum of 6 subframes.
71   * We really should try doing something more productive while we
72   * wait.
73   */
74  static void
mcp_sa11x0_write(struct mcp * mcp,unsigned int reg,unsigned int val)75  mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
76  {
77  	struct mcp_sa11x0 *m = priv(mcp);
78  	int ret = -ETIME;
79  	int i;
80  
81  	writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
82  
83  	for (i = 0; i < 2; i++) {
84  		udelay(mcp->rw_timeout);
85  		if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
86  			ret = 0;
87  			break;
88  		}
89  	}
90  
91  	if (ret < 0)
92  		printk(KERN_WARNING "mcp: write timed out\n");
93  }
94  
95  /*
96   * Read data from the device.  The bit should be set after 3 subframe
97   * times (each frame is 64 clocks).  We wait a maximum of 6 subframes.
98   * We really should try doing something more productive while we
99   * wait.
100   */
101  static unsigned int
mcp_sa11x0_read(struct mcp * mcp,unsigned int reg)102  mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
103  {
104  	struct mcp_sa11x0 *m = priv(mcp);
105  	int ret = -ETIME;
106  	int i;
107  
108  	writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
109  
110  	for (i = 0; i < 2; i++) {
111  		udelay(mcp->rw_timeout);
112  		if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
113  			ret = readl_relaxed(MCDR2(m)) & 0xffff;
114  			break;
115  		}
116  	}
117  
118  	if (ret < 0)
119  		printk(KERN_WARNING "mcp: read timed out\n");
120  
121  	return ret;
122  }
123  
mcp_sa11x0_enable(struct mcp * mcp)124  static void mcp_sa11x0_enable(struct mcp *mcp)
125  {
126  	struct mcp_sa11x0 *m = priv(mcp);
127  
128  	writel(-1, MCSR(m));
129  	m->mccr0 |= MCCR0_MCE;
130  	writel_relaxed(m->mccr0, MCCR0(m));
131  }
132  
mcp_sa11x0_disable(struct mcp * mcp)133  static void mcp_sa11x0_disable(struct mcp *mcp)
134  {
135  	struct mcp_sa11x0 *m = priv(mcp);
136  
137  	m->mccr0 &= ~MCCR0_MCE;
138  	writel_relaxed(m->mccr0, MCCR0(m));
139  }
140  
141  /*
142   * Our methods.
143   */
144  static struct mcp_ops mcp_sa11x0 = {
145  	.set_telecom_divisor	= mcp_sa11x0_set_telecom_divisor,
146  	.set_audio_divisor	= mcp_sa11x0_set_audio_divisor,
147  	.reg_write		= mcp_sa11x0_write,
148  	.reg_read		= mcp_sa11x0_read,
149  	.enable			= mcp_sa11x0_enable,
150  	.disable		= mcp_sa11x0_disable,
151  };
152  
mcp_sa11x0_probe(struct platform_device * dev)153  static int mcp_sa11x0_probe(struct platform_device *dev)
154  {
155  	struct mcp_plat_data *data = dev_get_platdata(&dev->dev);
156  	struct resource *mem0, *mem1;
157  	struct mcp_sa11x0 *m;
158  	struct mcp *mcp;
159  	int ret;
160  
161  	if (!data)
162  		return -ENODEV;
163  
164  	mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
165  	mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
166  	if (!mem0 || !mem1)
167  		return -ENXIO;
168  
169  	if (!request_mem_region(mem0->start, resource_size(mem0),
170  				DRIVER_NAME)) {
171  		ret = -EBUSY;
172  		goto err_mem0;
173  	}
174  
175  	if (!request_mem_region(mem1->start, resource_size(mem1),
176  				DRIVER_NAME)) {
177  		ret = -EBUSY;
178  		goto err_mem1;
179  	}
180  
181  	mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
182  	if (!mcp) {
183  		ret = -ENOMEM;
184  		goto err_alloc;
185  	}
186  
187  	mcp->owner		= THIS_MODULE;
188  	mcp->ops		= &mcp_sa11x0;
189  	mcp->sclk_rate		= data->sclk_rate;
190  
191  	m = priv(mcp);
192  	m->mccr0 = data->mccr0 | 0x7f7f;
193  	m->mccr1 = data->mccr1;
194  
195  	m->base0 = ioremap(mem0->start, resource_size(mem0));
196  	m->base1 = ioremap(mem1->start, resource_size(mem1));
197  	if (!m->base0 || !m->base1) {
198  		ret = -ENOMEM;
199  		goto err_ioremap;
200  	}
201  
202  	platform_set_drvdata(dev, mcp);
203  
204  	/*
205  	 * Initialise device.  Note that we initially
206  	 * set the sampling rate to minimum.
207  	 */
208  	writel_relaxed(-1, MCSR(m));
209  	writel_relaxed(m->mccr1, MCCR1(m));
210  	writel_relaxed(m->mccr0, MCCR0(m));
211  
212  	/*
213  	 * Calculate the read/write timeout (us) from the bit clock
214  	 * rate.  This is the period for 3 64-bit frames.  Always
215  	 * round this time up.
216  	 */
217  	mcp->rw_timeout = DIV_ROUND_UP(64 * 3 * 1000000, mcp->sclk_rate);
218  
219  	ret = mcp_host_add(mcp, data->codec_pdata);
220  	if (ret == 0)
221  		return 0;
222  
223   err_ioremap:
224  	iounmap(m->base1);
225  	iounmap(m->base0);
226  	mcp_host_free(mcp);
227   err_alloc:
228  	release_mem_region(mem1->start, resource_size(mem1));
229   err_mem1:
230  	release_mem_region(mem0->start, resource_size(mem0));
231   err_mem0:
232  	return ret;
233  }
234  
mcp_sa11x0_remove(struct platform_device * dev)235  static int mcp_sa11x0_remove(struct platform_device *dev)
236  {
237  	struct mcp *mcp = platform_get_drvdata(dev);
238  	struct mcp_sa11x0 *m = priv(mcp);
239  	struct resource *mem0, *mem1;
240  
241  	if (m->mccr0 & MCCR0_MCE)
242  		dev_warn(&dev->dev,
243  			 "device left active (missing disable call?)\n");
244  
245  	mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
246  	mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
247  
248  	mcp_host_del(mcp);
249  	iounmap(m->base1);
250  	iounmap(m->base0);
251  	mcp_host_free(mcp);
252  	release_mem_region(mem1->start, resource_size(mem1));
253  	release_mem_region(mem0->start, resource_size(mem0));
254  
255  	return 0;
256  }
257  
mcp_sa11x0_suspend(struct device * dev)258  static int mcp_sa11x0_suspend(struct device *dev)
259  {
260  	struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
261  
262  	if (m->mccr0 & MCCR0_MCE)
263  		dev_warn(dev, "device left active (missing disable call?)\n");
264  
265  	writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
266  
267  	return 0;
268  }
269  
mcp_sa11x0_resume(struct device * dev)270  static int mcp_sa11x0_resume(struct device *dev)
271  {
272  	struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
273  
274  	writel_relaxed(m->mccr1, MCCR1(m));
275  	writel_relaxed(m->mccr0, MCCR0(m));
276  
277  	return 0;
278  }
279  
280  static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
281  	.suspend = mcp_sa11x0_suspend,
282  	.freeze = mcp_sa11x0_suspend,
283  	.poweroff = mcp_sa11x0_suspend,
284  	.resume_noirq = mcp_sa11x0_resume,
285  	.thaw_noirq = mcp_sa11x0_resume,
286  	.restore_noirq = mcp_sa11x0_resume,
287  };
288  
289  static struct platform_driver mcp_sa11x0_driver = {
290  	.probe		= mcp_sa11x0_probe,
291  	.remove		= mcp_sa11x0_remove,
292  	.driver		= {
293  		.name	= DRIVER_NAME,
294  		.pm	= pm_sleep_ptr(&mcp_sa11x0_pm_ops),
295  	},
296  };
297  
298  /*
299   * This needs re-working
300   */
301  module_platform_driver(mcp_sa11x0_driver);
302  
303  MODULE_ALIAS("platform:" DRIVER_NAME);
304  MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
305  MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
306  MODULE_LICENSE("GPL");
307