root/drivers/mfd/mcp-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcp_bus_match
  2. mcp_bus_probe
  3. mcp_bus_remove
  4. mcp_set_telecom_divisor
  5. mcp_set_audio_divisor
  6. mcp_reg_write
  7. mcp_reg_read
  8. mcp_enable
  9. mcp_disable
  10. mcp_release
  11. mcp_host_alloc
  12. mcp_host_add
  13. mcp_host_del
  14. mcp_host_free
  15. mcp_driver_register
  16. mcp_driver_unregister
  17. mcp_init
  18. mcp_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  linux/drivers/mfd/mcp-core.c
   4  *
   5  *  Copyright (C) 2001 Russell King
   6  *
   7  *  Generic MCP (Multimedia Communications Port) layer.  All MCP locking
   8  *  is solely held within this file.
   9  */
  10 #include <linux/module.h>
  11 #include <linux/init.h>
  12 #include <linux/errno.h>
  13 #include <linux/smp.h>
  14 #include <linux/device.h>
  15 #include <linux/slab.h>
  16 #include <linux/string.h>
  17 #include <linux/mfd/mcp.h>
  18 
  19 
  20 #define to_mcp(d)               container_of(d, struct mcp, attached_device)
  21 #define to_mcp_driver(d)        container_of(d, struct mcp_driver, drv)
  22 
  23 static int mcp_bus_match(struct device *dev, struct device_driver *drv)
  24 {
  25         return 1;
  26 }
  27 
  28 static int mcp_bus_probe(struct device *dev)
  29 {
  30         struct mcp *mcp = to_mcp(dev);
  31         struct mcp_driver *drv = to_mcp_driver(dev->driver);
  32 
  33         return drv->probe(mcp);
  34 }
  35 
  36 static int mcp_bus_remove(struct device *dev)
  37 {
  38         struct mcp *mcp = to_mcp(dev);
  39         struct mcp_driver *drv = to_mcp_driver(dev->driver);
  40 
  41         drv->remove(mcp);
  42         return 0;
  43 }
  44 
  45 static struct bus_type mcp_bus_type = {
  46         .name           = "mcp",
  47         .match          = mcp_bus_match,
  48         .probe          = mcp_bus_probe,
  49         .remove         = mcp_bus_remove,
  50 };
  51 
  52 /**
  53  *      mcp_set_telecom_divisor - set the telecom divisor
  54  *      @mcp: MCP interface structure
  55  *      @div: SIB clock divisor
  56  *
  57  *      Set the telecom divisor on the MCP interface.  The resulting
  58  *      sample rate is SIBCLOCK/div.
  59  */
  60 void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
  61 {
  62         unsigned long flags;
  63 
  64         spin_lock_irqsave(&mcp->lock, flags);
  65         mcp->ops->set_telecom_divisor(mcp, div);
  66         spin_unlock_irqrestore(&mcp->lock, flags);
  67 }
  68 EXPORT_SYMBOL(mcp_set_telecom_divisor);
  69 
  70 /**
  71  *      mcp_set_audio_divisor - set the audio divisor
  72  *      @mcp: MCP interface structure
  73  *      @div: SIB clock divisor
  74  *
  75  *      Set the audio divisor on the MCP interface.
  76  */
  77 void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
  78 {
  79         unsigned long flags;
  80 
  81         spin_lock_irqsave(&mcp->lock, flags);
  82         mcp->ops->set_audio_divisor(mcp, div);
  83         spin_unlock_irqrestore(&mcp->lock, flags);
  84 }
  85 EXPORT_SYMBOL(mcp_set_audio_divisor);
  86 
  87 /**
  88  *      mcp_reg_write - write a device register
  89  *      @mcp: MCP interface structure
  90  *      @reg: 4-bit register index
  91  *      @val: 16-bit data value
  92  *
  93  *      Write a device register.  The MCP interface must be enabled
  94  *      to prevent this function hanging.
  95  */
  96 void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
  97 {
  98         unsigned long flags;
  99 
 100         spin_lock_irqsave(&mcp->lock, flags);
 101         mcp->ops->reg_write(mcp, reg, val);
 102         spin_unlock_irqrestore(&mcp->lock, flags);
 103 }
 104 EXPORT_SYMBOL(mcp_reg_write);
 105 
 106 /**
 107  *      mcp_reg_read - read a device register
 108  *      @mcp: MCP interface structure
 109  *      @reg: 4-bit register index
 110  *
 111  *      Read a device register and return its value.  The MCP interface
 112  *      must be enabled to prevent this function hanging.
 113  */
 114 unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
 115 {
 116         unsigned long flags;
 117         unsigned int val;
 118 
 119         spin_lock_irqsave(&mcp->lock, flags);
 120         val = mcp->ops->reg_read(mcp, reg);
 121         spin_unlock_irqrestore(&mcp->lock, flags);
 122 
 123         return val;
 124 }
 125 EXPORT_SYMBOL(mcp_reg_read);
 126 
 127 /**
 128  *      mcp_enable - enable the MCP interface
 129  *      @mcp: MCP interface to enable
 130  *
 131  *      Enable the MCP interface.  Each call to mcp_enable will need
 132  *      a corresponding call to mcp_disable to disable the interface.
 133  */
 134 void mcp_enable(struct mcp *mcp)
 135 {
 136         unsigned long flags;
 137 
 138         spin_lock_irqsave(&mcp->lock, flags);
 139         if (mcp->use_count++ == 0)
 140                 mcp->ops->enable(mcp);
 141         spin_unlock_irqrestore(&mcp->lock, flags);
 142 }
 143 EXPORT_SYMBOL(mcp_enable);
 144 
 145 /**
 146  *      mcp_disable - disable the MCP interface
 147  *      @mcp: MCP interface to disable
 148  *
 149  *      Disable the MCP interface.  The MCP interface will only be
 150  *      disabled once the number of calls to mcp_enable matches the
 151  *      number of calls to mcp_disable.
 152  */
 153 void mcp_disable(struct mcp *mcp)
 154 {
 155         unsigned long flags;
 156 
 157         spin_lock_irqsave(&mcp->lock, flags);
 158         if (--mcp->use_count == 0)
 159                 mcp->ops->disable(mcp);
 160         spin_unlock_irqrestore(&mcp->lock, flags);
 161 }
 162 EXPORT_SYMBOL(mcp_disable);
 163 
 164 static void mcp_release(struct device *dev)
 165 {
 166         struct mcp *mcp = container_of(dev, struct mcp, attached_device);
 167 
 168         kfree(mcp);
 169 }
 170 
 171 struct mcp *mcp_host_alloc(struct device *parent, size_t size)
 172 {
 173         struct mcp *mcp;
 174 
 175         mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
 176         if (mcp) {
 177                 spin_lock_init(&mcp->lock);
 178                 device_initialize(&mcp->attached_device);
 179                 mcp->attached_device.parent = parent;
 180                 mcp->attached_device.bus = &mcp_bus_type;
 181                 mcp->attached_device.dma_mask = parent->dma_mask;
 182                 mcp->attached_device.release = mcp_release;
 183         }
 184         return mcp;
 185 }
 186 EXPORT_SYMBOL(mcp_host_alloc);
 187 
 188 int mcp_host_add(struct mcp *mcp, void *pdata)
 189 {
 190         mcp->attached_device.platform_data = pdata;
 191         dev_set_name(&mcp->attached_device, "mcp0");
 192         return device_add(&mcp->attached_device);
 193 }
 194 EXPORT_SYMBOL(mcp_host_add);
 195 
 196 void mcp_host_del(struct mcp *mcp)
 197 {
 198         device_del(&mcp->attached_device);
 199 }
 200 EXPORT_SYMBOL(mcp_host_del);
 201 
 202 void mcp_host_free(struct mcp *mcp)
 203 {
 204         put_device(&mcp->attached_device);
 205 }
 206 EXPORT_SYMBOL(mcp_host_free);
 207 
 208 int mcp_driver_register(struct mcp_driver *mcpdrv)
 209 {
 210         mcpdrv->drv.bus = &mcp_bus_type;
 211         return driver_register(&mcpdrv->drv);
 212 }
 213 EXPORT_SYMBOL(mcp_driver_register);
 214 
 215 void mcp_driver_unregister(struct mcp_driver *mcpdrv)
 216 {
 217         driver_unregister(&mcpdrv->drv);
 218 }
 219 EXPORT_SYMBOL(mcp_driver_unregister);
 220 
 221 static int __init mcp_init(void)
 222 {
 223         return bus_register(&mcp_bus_type);
 224 }
 225 
 226 static void __exit mcp_exit(void)
 227 {
 228         bus_unregister(&mcp_bus_type);
 229 }
 230 
 231 module_init(mcp_init);
 232 module_exit(mcp_exit);
 233 
 234 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 235 MODULE_DESCRIPTION("Core multimedia communications port driver");
 236 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */