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 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 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 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 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 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 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 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 235 static void 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 256 static int mcp_sa11x0_suspend(struct device *dev) 257 { 258 struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); 259 260 if (m->mccr0 & MCCR0_MCE) 261 dev_warn(dev, "device left active (missing disable call?)\n"); 262 263 writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m)); 264 265 return 0; 266 } 267 268 static int mcp_sa11x0_resume(struct device *dev) 269 { 270 struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); 271 272 writel_relaxed(m->mccr1, MCCR1(m)); 273 writel_relaxed(m->mccr0, MCCR0(m)); 274 275 return 0; 276 } 277 278 static const struct dev_pm_ops mcp_sa11x0_pm_ops = { 279 .suspend = mcp_sa11x0_suspend, 280 .freeze = mcp_sa11x0_suspend, 281 .poweroff = mcp_sa11x0_suspend, 282 .resume_noirq = mcp_sa11x0_resume, 283 .thaw_noirq = mcp_sa11x0_resume, 284 .restore_noirq = mcp_sa11x0_resume, 285 }; 286 287 static struct platform_driver mcp_sa11x0_driver = { 288 .probe = mcp_sa11x0_probe, 289 .remove_new = mcp_sa11x0_remove, 290 .driver = { 291 .name = DRIVER_NAME, 292 .pm = pm_sleep_ptr(&mcp_sa11x0_pm_ops), 293 }, 294 }; 295 296 /* 297 * This needs re-working 298 */ 299 module_platform_driver(mcp_sa11x0_driver); 300 301 MODULE_ALIAS("platform:" DRIVER_NAME); 302 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); 303 MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); 304 MODULE_LICENSE("GPL"); 305