1*dfe66a18SJeeja KP /* 2*dfe66a18SJeeja KP * hdac-ext-bus.c - HD-audio extended core bus functions. 3*dfe66a18SJeeja KP * 4*dfe66a18SJeeja KP * Copyright (C) 2014-2015 Intel Corp 5*dfe66a18SJeeja KP * Author: Jeeja KP <jeeja.kp@intel.com> 6*dfe66a18SJeeja KP * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7*dfe66a18SJeeja KP * 8*dfe66a18SJeeja KP * This program is free software; you can redistribute it and/or modify 9*dfe66a18SJeeja KP * it under the terms of the GNU General Public License as published by 10*dfe66a18SJeeja KP * the Free Software Foundation; version 2 of the License. 11*dfe66a18SJeeja KP * 12*dfe66a18SJeeja KP * This program is distributed in the hope that it will be useful, but 13*dfe66a18SJeeja KP * WITHOUT ANY WARRANTY; without even the implied warranty of 14*dfe66a18SJeeja KP * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*dfe66a18SJeeja KP * General Public License for more details. 16*dfe66a18SJeeja KP * 17*dfe66a18SJeeja KP * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18*dfe66a18SJeeja KP */ 19*dfe66a18SJeeja KP 20*dfe66a18SJeeja KP #include <linux/module.h> 21*dfe66a18SJeeja KP #include <linux/slab.h> 22*dfe66a18SJeeja KP #include <sound/hdaudio_ext.h> 23*dfe66a18SJeeja KP 24*dfe66a18SJeeja KP MODULE_DESCRIPTION("HDA extended core"); 25*dfe66a18SJeeja KP MODULE_LICENSE("GPL v2"); 26*dfe66a18SJeeja KP 27*dfe66a18SJeeja KP /** 28*dfe66a18SJeeja KP * snd_hdac_ext_bus_init - initialize a HD-audio extended bus 29*dfe66a18SJeeja KP * @ebus: the pointer to extended bus object 30*dfe66a18SJeeja KP * @dev: device pointer 31*dfe66a18SJeeja KP * @ops: bus verb operators 32*dfe66a18SJeeja KP * @io_ops: lowlevel I/O operators 33*dfe66a18SJeeja KP * 34*dfe66a18SJeeja KP * Returns 0 if successful, or a negative error code. 35*dfe66a18SJeeja KP */ 36*dfe66a18SJeeja KP int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, 37*dfe66a18SJeeja KP const struct hdac_bus_ops *ops, 38*dfe66a18SJeeja KP const struct hdac_io_ops *io_ops) 39*dfe66a18SJeeja KP { 40*dfe66a18SJeeja KP int ret; 41*dfe66a18SJeeja KP static int idx; 42*dfe66a18SJeeja KP 43*dfe66a18SJeeja KP ret = snd_hdac_bus_init(&ebus->bus, dev, ops, io_ops); 44*dfe66a18SJeeja KP if (ret < 0) 45*dfe66a18SJeeja KP return ret; 46*dfe66a18SJeeja KP 47*dfe66a18SJeeja KP INIT_LIST_HEAD(&ebus->hlink_list); 48*dfe66a18SJeeja KP ebus->idx = idx++; 49*dfe66a18SJeeja KP 50*dfe66a18SJeeja KP return 0; 51*dfe66a18SJeeja KP } 52*dfe66a18SJeeja KP EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init); 53*dfe66a18SJeeja KP 54*dfe66a18SJeeja KP /** 55*dfe66a18SJeeja KP * snd_hdac_ext_bus_exit - clean up a HD-audio extended bus 56*dfe66a18SJeeja KP * @ebus: the pointer to extended bus object 57*dfe66a18SJeeja KP */ 58*dfe66a18SJeeja KP void snd_hdac_ext_bus_exit(struct hdac_ext_bus *ebus) 59*dfe66a18SJeeja KP { 60*dfe66a18SJeeja KP snd_hdac_bus_exit(&ebus->bus); 61*dfe66a18SJeeja KP WARN_ON(!list_empty(&ebus->hlink_list)); 62*dfe66a18SJeeja KP } 63*dfe66a18SJeeja KP EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_exit); 64*dfe66a18SJeeja KP 65*dfe66a18SJeeja KP static void default_release(struct device *dev) 66*dfe66a18SJeeja KP { 67*dfe66a18SJeeja KP snd_hdac_ext_bus_device_exit(container_of(dev, struct hdac_device, dev)); 68*dfe66a18SJeeja KP } 69*dfe66a18SJeeja KP 70*dfe66a18SJeeja KP /** 71*dfe66a18SJeeja KP * snd_hdac_ext_device_init - initialize the HDA extended codec base device 72*dfe66a18SJeeja KP * @ebus: hdac extended bus to attach to 73*dfe66a18SJeeja KP * @addr: codec address 74*dfe66a18SJeeja KP * 75*dfe66a18SJeeja KP * Returns zero for success or a negative error code. 76*dfe66a18SJeeja KP */ 77*dfe66a18SJeeja KP int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr) 78*dfe66a18SJeeja KP { 79*dfe66a18SJeeja KP struct hdac_device *hdev = NULL; 80*dfe66a18SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 81*dfe66a18SJeeja KP char name[15]; 82*dfe66a18SJeeja KP int ret; 83*dfe66a18SJeeja KP 84*dfe66a18SJeeja KP hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 85*dfe66a18SJeeja KP if (!hdev) 86*dfe66a18SJeeja KP return -ENOMEM; 87*dfe66a18SJeeja KP 88*dfe66a18SJeeja KP snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr); 89*dfe66a18SJeeja KP 90*dfe66a18SJeeja KP ret = snd_hdac_device_init(hdev, bus, name, addr); 91*dfe66a18SJeeja KP if (ret < 0) { 92*dfe66a18SJeeja KP dev_err(bus->dev, "device init failed for hdac device\n"); 93*dfe66a18SJeeja KP return ret; 94*dfe66a18SJeeja KP } 95*dfe66a18SJeeja KP hdev->type = HDA_DEV_ASOC; 96*dfe66a18SJeeja KP hdev->dev.release = default_release; 97*dfe66a18SJeeja KP 98*dfe66a18SJeeja KP ret = snd_hdac_device_register(hdev); 99*dfe66a18SJeeja KP if (ret) { 100*dfe66a18SJeeja KP dev_err(bus->dev, "failed to register hdac device\n"); 101*dfe66a18SJeeja KP snd_hdac_ext_bus_device_exit(hdev); 102*dfe66a18SJeeja KP return ret; 103*dfe66a18SJeeja KP } 104*dfe66a18SJeeja KP return 0; 105*dfe66a18SJeeja KP } 106*dfe66a18SJeeja KP EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_init); 107*dfe66a18SJeeja KP 108*dfe66a18SJeeja KP /** 109*dfe66a18SJeeja KP * snd_hdac_ext_bus_device_exit - clean up a HD-audio extended codec base device 110*dfe66a18SJeeja KP * @hdev: hdac device to clean up 111*dfe66a18SJeeja KP */ 112*dfe66a18SJeeja KP void snd_hdac_ext_bus_device_exit(struct hdac_device *hdev) 113*dfe66a18SJeeja KP { 114*dfe66a18SJeeja KP snd_hdac_device_exit(hdev); 115*dfe66a18SJeeja KP kfree(hdev); 116*dfe66a18SJeeja KP } 117*dfe66a18SJeeja KP EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_device_exit); 118