1/* 2 * i2sbus driver 3 * 4 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> 5 * 6 * GPL v2, can be found in COPYING. 7 */ 8 9#include <linux/module.h> 10#include <linux/pci.h> 11#include <linux/interrupt.h> 12#include <linux/dma-mapping.h> 13 14#include <sound/driver.h> 15#include <sound/core.h> 16 17#include <asm/macio.h> 18#include <asm/dbdma.h> 19 20#include "../soundbus.h" 21#include "i2sbus.h" 22 23MODULE_LICENSE("GPL"); 24MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 25MODULE_DESCRIPTION("Apple Soundbus: I2S support"); 26 27static int force; 28module_param(force, int, 0444); 29MODULE_PARM_DESC(force, "Force loading i2sbus even when" 30 " no layout-id property is present"); 31 32static struct of_device_id i2sbus_match[] = { 33 { .name = "i2s" }, 34 { } 35}; 36 37MODULE_DEVICE_TABLE(of, i2sbus_match); 38 39static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, 40 struct dbdma_command_mem *r, 41 int numcmds) 42{ 43 /* one more for rounding, one for branch back, one for stop command */ 44 r->size = (numcmds + 3) * sizeof(struct dbdma_cmd); 45 /* We use the PCI APIs for now until the generic one gets fixed 46 * enough or until we get some macio-specific versions 47 */ 48 r->space = dma_alloc_coherent( 49 &macio_get_pci_dev(i2sdev->macio)->dev, 50 r->size, 51 &r->bus_addr, 52 GFP_KERNEL); 53 54 if (!r->space) return -ENOMEM; 55 56 memset(r->space, 0, r->size); 57 r->cmds = (void*)DBDMA_ALIGN(r->space); 58 r->bus_cmd_start = r->bus_addr + 59 (dma_addr_t)((char*)r->cmds - (char*)r->space); 60 61 return 0; 62} 63 64static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, 65 struct dbdma_command_mem *r) 66{ 67 if (!r->space) return; 68 69 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, 70 r->size, r->space, r->bus_addr); 71} 72 73static void i2sbus_release_dev(struct device *dev) 74{ 75 struct i2sbus_dev *i2sdev; 76 int i; 77 78 i2sdev = container_of(dev, struct i2sbus_dev, sound.ofdev.dev); 79 80 if (i2sdev->intfregs) iounmap(i2sdev->intfregs); 81 if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); 82 if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); 83 for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) 84 if (i2sdev->allocated_resource[i]) 85 release_and_free_resource(i2sdev->allocated_resource[i]); 86 free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); 87 free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); 88 for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) 89 free_irq(i2sdev->interrupts[i], i2sdev); 90 i2sbus_control_remove_dev(i2sdev->control, i2sdev); 91 mutex_destroy(&i2sdev->lock); 92 kfree(i2sdev); 93} 94 95static irqreturn_t i2sbus_bus_intr(int irq, void *devid) 96{ 97 struct i2sbus_dev *dev = devid; 98 u32 intreg; 99 100 spin_lock(&dev->low_lock); 101 intreg = in_le32(&dev->intfregs->intr_ctl); 102 103 /* acknowledge interrupt reasons */ 104 out_le32(&dev->intfregs->intr_ctl, intreg); 105 106 spin_unlock(&dev->low_lock); 107 108 return IRQ_HANDLED; 109} 110 111 112static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index, 113 int layout, struct resource *res) 114{ 115 struct device_node *parent; 116 int pindex, rc = -ENXIO; 117 const u32 *reg; 118 119 /* Machines with layout 76 and 36 (K2 based) have a weird device 120 * tree what we need to special case. 121 * Normal machines just fetch the resource from the i2s-X node. 122 * Darwin further divides normal machines into old and new layouts 123 * with a subtely different code path but that doesn't seem necessary 124 * in practice, they just bloated it. In addition, even on our K2 125 * case the i2s-modem node, if we ever want to handle it, uses the 126 * normal layout 127 */ 128 if (layout != 76 && layout != 36) 129 return of_address_to_resource(np, index, res); 130 131 parent = of_get_parent(np); 132 pindex = (index == aoa_resource_i2smmio) ? 0 : 1; 133 rc = of_address_to_resource(parent, pindex, res); 134 if (rc) 135 goto bail; 136 reg = of_get_property(np, "reg", NULL); 137 if (reg == NULL) { 138 rc = -ENXIO; 139 goto bail; 140 } 141 res->start += reg[index * 2]; 142 res->end = res->start + reg[index * 2 + 1] - 1; 143 bail: 144 of_node_put(parent); 145 return rc; 146} 147 148static int i2sbus_add_dev(struct macio_dev *macio, 149 struct i2sbus_control *control, 150 struct device_node *np) 151{ 152 struct i2sbus_dev *dev; 153 struct device_node *child = NULL, *sound = NULL; 154 struct resource *r; 155 int i, layout = 0, rlen; 156 static const char *rnames[] = { "i2sbus: %s (control)", 157 "i2sbus: %s (tx)", 158 "i2sbus: %s (rx)" }; 159 static irq_handler_t ints[] = { 160 i2sbus_bus_intr, 161 i2sbus_tx_intr, 162 i2sbus_rx_intr 163 }; 164 165 if (strlen(np->name) != 5) 166 return 0; 167 if (strncmp(np->name, "i2s-", 4)) 168 return 0; 169 170 dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL); 171 if (!dev) 172 return 0; 173 174 i = 0; 175 while ((child = of_get_next_child(np, child))) { 176 if (strcmp(child->name, "sound") == 0) { 177 i++; 178 sound = child; 179 } 180 } 181 if (i == 1) { 182 const u32 *layout_id = 183 of_get_property(sound, "layout-id", NULL); 184 if (layout_id) { 185 layout = *layout_id; 186 snprintf(dev->sound.modalias, 32, 187 "sound-layout-%d", layout); 188 force = 1; 189 } 190 } 191 /* for the time being, until we can handle non-layout-id 192 * things in some fabric, refuse to attach if there is no 193 * layout-id property or we haven't been forced to attach. 194 * When there are two i2s busses and only one has a layout-id, 195 * then this depends on the order, but that isn't important 196 * either as the second one in that case is just a modem. */ 197 if (!force) { 198 kfree(dev); 199 return -ENODEV; 200 } 201 202 mutex_init(&dev->lock); 203 spin_lock_init(&dev->low_lock); 204 dev->sound.ofdev.node = np; 205 dev->sound.ofdev.dma_mask = macio->ofdev.dma_mask; 206 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.dma_mask; 207 dev->sound.ofdev.dev.parent = &macio->ofdev.dev; 208 dev->sound.ofdev.dev.release = i2sbus_release_dev; 209 dev->sound.attach_codec = i2sbus_attach_codec; 210 dev->sound.detach_codec = i2sbus_detach_codec; 211 dev->sound.pcmid = -1; 212 dev->macio = macio; 213 dev->control = control; 214 dev->bus_number = np->name[4] - 'a'; 215 INIT_LIST_HEAD(&dev->sound.codec_list); 216 217 for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { 218 dev->interrupts[i] = -1; 219 snprintf(dev->rnames[i], sizeof(dev->rnames[i]), 220 rnames[i], np->name); 221 } 222 for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { 223 int irq = irq_of_parse_and_map(np, i); 224 if (request_irq(irq, ints[i], 0, dev->rnames[i], dev)) 225 goto err; 226 dev->interrupts[i] = irq; 227 } 228 229 230 for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { 231 if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i])) 232 goto err; 233 /* If only we could use our resource dev->resources[i]... 234 * but request_resource doesn't know about parents and 235 * contained resources... 236 */ 237 dev->allocated_resource[i] = 238 request_mem_region(dev->resources[i].start, 239 dev->resources[i].end - 240 dev->resources[i].start + 1, 241 dev->rnames[i]); 242 if (!dev->allocated_resource[i]) { 243 printk(KERN_ERR "i2sbus: failed to claim resource %d!\n", i); 244 goto err; 245 } 246 } 247 248 r = &dev->resources[aoa_resource_i2smmio]; 249 rlen = r->end - r->start + 1; 250 if (rlen < sizeof(struct i2s_interface_regs)) 251 goto err; 252 dev->intfregs = ioremap(r->start, rlen); 253 254 r = &dev->resources[aoa_resource_txdbdma]; 255 rlen = r->end - r->start + 1; 256 if (rlen < sizeof(struct dbdma_regs)) 257 goto err; 258 dev->out.dbdma = ioremap(r->start, rlen); 259 260 r = &dev->resources[aoa_resource_rxdbdma]; 261 rlen = r->end - r->start + 1; 262 if (rlen < sizeof(struct dbdma_regs)) 263 goto err; 264 dev->in.dbdma = ioremap(r->start, rlen); 265 266 if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma) 267 goto err; 268 269 if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring, 270 MAX_DBDMA_COMMANDS)) 271 goto err; 272 if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring, 273 MAX_DBDMA_COMMANDS)) 274 goto err; 275 276 if (i2sbus_control_add_dev(dev->control, dev)) { 277 printk(KERN_ERR "i2sbus: control layer didn't like bus\n"); 278 goto err; 279 } 280 281 if (soundbus_add_one(&dev->sound)) { 282 printk(KERN_DEBUG "i2sbus: device registration error!\n"); 283 goto err; 284 } 285 286 /* enable this cell */ 287 i2sbus_control_cell(dev->control, dev, 1); 288 i2sbus_control_enable(dev->control, dev); 289 i2sbus_control_clock(dev->control, dev, 1); 290 291 return 1; 292 err: 293 for (i=0;i<3;i++) 294 if (dev->interrupts[i] != -1) 295 free_irq(dev->interrupts[i], dev); 296 free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring); 297 free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring); 298 if (dev->intfregs) iounmap(dev->intfregs); 299 if (dev->out.dbdma) iounmap(dev->out.dbdma); 300 if (dev->in.dbdma) iounmap(dev->in.dbdma); 301 for (i=0;i<3;i++) 302 if (dev->allocated_resource[i]) 303 release_and_free_resource(dev->allocated_resource[i]); 304 mutex_destroy(&dev->lock); 305 kfree(dev); 306 return 0; 307} 308 309static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) 310{ 311 struct device_node *np = NULL; 312 int got = 0, err; 313 struct i2sbus_control *control = NULL; 314 315 err = i2sbus_control_init(dev, &control); 316 if (err) 317 return err; 318 if (!control) { 319 printk(KERN_ERR "i2sbus_control_init API breakage\n"); 320 return -ENODEV; 321 } 322 323 while ((np = of_get_next_child(dev->ofdev.node, np))) { 324 if (of_device_is_compatible(np, "i2sbus") || 325 of_device_is_compatible(np, "i2s-modem")) { 326 got += i2sbus_add_dev(dev, control, np); 327 } 328 } 329 330 if (!got) { 331 /* found none, clean up */ 332 i2sbus_control_destroy(control); 333 return -ENODEV; 334 } 335 336 dev->ofdev.dev.driver_data = control; 337 338 return 0; 339} 340 341static int i2sbus_remove(struct macio_dev* dev) 342{ 343 struct i2sbus_control *control = dev->ofdev.dev.driver_data; 344 struct i2sbus_dev *i2sdev, *tmp; 345 346 list_for_each_entry_safe(i2sdev, tmp, &control->list, item) 347 soundbus_remove_one(&i2sdev->sound); 348 349 return 0; 350} 351 352#ifdef CONFIG_PM 353static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) 354{ 355 struct i2sbus_control *control = dev->ofdev.dev.driver_data; 356 struct codec_info_item *cii; 357 struct i2sbus_dev* i2sdev; 358 int err, ret = 0; 359 360 list_for_each_entry(i2sdev, &control->list, item) { 361 /* Notify Alsa */ 362 if (i2sdev->sound.pcm) { 363 /* Suspend PCM streams */ 364 snd_pcm_suspend_all(i2sdev->sound.pcm); 365 } 366 367 /* Notify codecs */ 368 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { 369 err = 0; 370 if (cii->codec->suspend) 371 err = cii->codec->suspend(cii, state); 372 if (err) 373 ret = err; 374 } 375 376 /* wait until streams are stopped */ 377 i2sbus_wait_for_stop_both(i2sdev); 378 } 379 380 return ret; 381} 382 383static int i2sbus_resume(struct macio_dev* dev) 384{ 385 struct i2sbus_control *control = dev->ofdev.dev.driver_data; 386 struct codec_info_item *cii; 387 struct i2sbus_dev* i2sdev; 388 int err, ret = 0; 389 390 list_for_each_entry(i2sdev, &control->list, item) { 391 /* reset i2s bus format etc. */ 392 i2sbus_pcm_prepare_both(i2sdev); 393 394 /* Notify codecs so they can re-initialize */ 395 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { 396 err = 0; 397 if (cii->codec->resume) 398 err = cii->codec->resume(cii); 399 if (err) 400 ret = err; 401 } 402 } 403 404 return ret; 405} 406#endif /* CONFIG_PM */ 407 408static int i2sbus_shutdown(struct macio_dev* dev) 409{ 410 return 0; 411} 412 413static struct macio_driver i2sbus_drv = { 414 .name = "soundbus-i2s", 415 .owner = THIS_MODULE, 416 .match_table = i2sbus_match, 417 .probe = i2sbus_probe, 418 .remove = i2sbus_remove, 419#ifdef CONFIG_PM 420 .suspend = i2sbus_suspend, 421 .resume = i2sbus_resume, 422#endif 423 .shutdown = i2sbus_shutdown, 424}; 425 426static int __init soundbus_i2sbus_init(void) 427{ 428 return macio_register_driver(&i2sbus_drv); 429} 430 431static void __exit soundbus_i2sbus_exit(void) 432{ 433 macio_unregister_driver(&i2sbus_drv); 434} 435 436module_init(soundbus_i2sbus_init); 437module_exit(soundbus_i2sbus_exit); 438