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