0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/errno.h>
0013 #include <linux/smp.h>
0014 #include <linux/device.h>
0015 #include <linux/slab.h>
0016 #include <linux/string.h>
0017 #include <linux/mfd/mcp.h>
0018
0019
0020 #define to_mcp(d) container_of(d, struct mcp, attached_device)
0021 #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
0022
0023 static int mcp_bus_match(struct device *dev, struct device_driver *drv)
0024 {
0025 return 1;
0026 }
0027
0028 static int mcp_bus_probe(struct device *dev)
0029 {
0030 struct mcp *mcp = to_mcp(dev);
0031 struct mcp_driver *drv = to_mcp_driver(dev->driver);
0032
0033 return drv->probe(mcp);
0034 }
0035
0036 static void mcp_bus_remove(struct device *dev)
0037 {
0038 struct mcp *mcp = to_mcp(dev);
0039 struct mcp_driver *drv = to_mcp_driver(dev->driver);
0040
0041 drv->remove(mcp);
0042 }
0043
0044 static struct bus_type mcp_bus_type = {
0045 .name = "mcp",
0046 .match = mcp_bus_match,
0047 .probe = mcp_bus_probe,
0048 .remove = mcp_bus_remove,
0049 };
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
0060 {
0061 unsigned long flags;
0062
0063 spin_lock_irqsave(&mcp->lock, flags);
0064 mcp->ops->set_telecom_divisor(mcp, div);
0065 spin_unlock_irqrestore(&mcp->lock, flags);
0066 }
0067 EXPORT_SYMBOL(mcp_set_telecom_divisor);
0068
0069
0070
0071
0072
0073
0074
0075
0076 void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
0077 {
0078 unsigned long flags;
0079
0080 spin_lock_irqsave(&mcp->lock, flags);
0081 mcp->ops->set_audio_divisor(mcp, div);
0082 spin_unlock_irqrestore(&mcp->lock, flags);
0083 }
0084 EXPORT_SYMBOL(mcp_set_audio_divisor);
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
0096 {
0097 unsigned long flags;
0098
0099 spin_lock_irqsave(&mcp->lock, flags);
0100 mcp->ops->reg_write(mcp, reg, val);
0101 spin_unlock_irqrestore(&mcp->lock, flags);
0102 }
0103 EXPORT_SYMBOL(mcp_reg_write);
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
0114 {
0115 unsigned long flags;
0116 unsigned int val;
0117
0118 spin_lock_irqsave(&mcp->lock, flags);
0119 val = mcp->ops->reg_read(mcp, reg);
0120 spin_unlock_irqrestore(&mcp->lock, flags);
0121
0122 return val;
0123 }
0124 EXPORT_SYMBOL(mcp_reg_read);
0125
0126
0127
0128
0129
0130
0131
0132
0133 void mcp_enable(struct mcp *mcp)
0134 {
0135 unsigned long flags;
0136
0137 spin_lock_irqsave(&mcp->lock, flags);
0138 if (mcp->use_count++ == 0)
0139 mcp->ops->enable(mcp);
0140 spin_unlock_irqrestore(&mcp->lock, flags);
0141 }
0142 EXPORT_SYMBOL(mcp_enable);
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 void mcp_disable(struct mcp *mcp)
0153 {
0154 unsigned long flags;
0155
0156 spin_lock_irqsave(&mcp->lock, flags);
0157 if (--mcp->use_count == 0)
0158 mcp->ops->disable(mcp);
0159 spin_unlock_irqrestore(&mcp->lock, flags);
0160 }
0161 EXPORT_SYMBOL(mcp_disable);
0162
0163 static void mcp_release(struct device *dev)
0164 {
0165 struct mcp *mcp = container_of(dev, struct mcp, attached_device);
0166
0167 kfree(mcp);
0168 }
0169
0170 struct mcp *mcp_host_alloc(struct device *parent, size_t size)
0171 {
0172 struct mcp *mcp;
0173
0174 mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
0175 if (mcp) {
0176 spin_lock_init(&mcp->lock);
0177 device_initialize(&mcp->attached_device);
0178 mcp->attached_device.parent = parent;
0179 mcp->attached_device.bus = &mcp_bus_type;
0180 mcp->attached_device.dma_mask = parent->dma_mask;
0181 mcp->attached_device.release = mcp_release;
0182 }
0183 return mcp;
0184 }
0185 EXPORT_SYMBOL(mcp_host_alloc);
0186
0187 int mcp_host_add(struct mcp *mcp, void *pdata)
0188 {
0189 mcp->attached_device.platform_data = pdata;
0190 dev_set_name(&mcp->attached_device, "mcp0");
0191 return device_add(&mcp->attached_device);
0192 }
0193 EXPORT_SYMBOL(mcp_host_add);
0194
0195 void mcp_host_del(struct mcp *mcp)
0196 {
0197 device_del(&mcp->attached_device);
0198 }
0199 EXPORT_SYMBOL(mcp_host_del);
0200
0201 void mcp_host_free(struct mcp *mcp)
0202 {
0203 put_device(&mcp->attached_device);
0204 }
0205 EXPORT_SYMBOL(mcp_host_free);
0206
0207 int mcp_driver_register(struct mcp_driver *mcpdrv)
0208 {
0209 mcpdrv->drv.bus = &mcp_bus_type;
0210 return driver_register(&mcpdrv->drv);
0211 }
0212 EXPORT_SYMBOL(mcp_driver_register);
0213
0214 void mcp_driver_unregister(struct mcp_driver *mcpdrv)
0215 {
0216 driver_unregister(&mcpdrv->drv);
0217 }
0218 EXPORT_SYMBOL(mcp_driver_unregister);
0219
0220 static int __init mcp_init(void)
0221 {
0222 return bus_register(&mcp_bus_type);
0223 }
0224
0225 static void __exit mcp_exit(void)
0226 {
0227 bus_unregister(&mcp_bus_type);
0228 }
0229
0230 module_init(mcp_init);
0231 module_exit(mcp_exit);
0232
0233 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
0234 MODULE_DESCRIPTION("Core multimedia communications port driver");
0235 MODULE_LICENSE("GPL");