linux/drivers/media/pci/bt8xx/bttv-gpio.c
<<
>>
Prefs
   1/*
   2
   3    bttv-gpio.c  --  gpio sub drivers
   4
   5    sysfs-based sub driver interface for bttv
   6    mainly intended for gpio access
   7
   8
   9    Copyright (C) 1996,97,98 Ralph  Metzler (rjkm@thp.uni-koeln.de)
  10                           & Marcus Metzler (mocm@thp.uni-koeln.de)
  11    (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
  12
  13    This program is free software; you can redistribute it and/or modify
  14    it under the terms of the GNU General Public License as published by
  15    the Free Software Foundation; either version 2 of the License, or
  16    (at your option) any later version.
  17
  18    This program is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22
  23    You should have received a copy of the GNU General Public License
  24    along with this program; if not, write to the Free Software
  25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26
  27*/
  28
  29#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  30
  31#include <linux/module.h>
  32#include <linux/init.h>
  33#include <linux/delay.h>
  34#include <linux/device.h>
  35#include <linux/slab.h>
  36#include <asm/io.h>
  37
  38#include "bttvp.h"
  39
  40/* ----------------------------------------------------------------------- */
  41/* internal: the bttv "bus"                                                */
  42
  43static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
  44{
  45        struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
  46        int len = strlen(sub->wanted);
  47
  48        if (0 == strncmp(dev_name(dev), sub->wanted, len))
  49                return 1;
  50        return 0;
  51}
  52
  53static int bttv_sub_probe(struct device *dev)
  54{
  55        struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
  56        struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
  57
  58        return sub->probe ? sub->probe(sdev) : -ENODEV;
  59}
  60
  61static int bttv_sub_remove(struct device *dev)
  62{
  63        struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
  64        struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
  65
  66        if (sub->remove)
  67                sub->remove(sdev);
  68        return 0;
  69}
  70
  71struct bus_type bttv_sub_bus_type = {
  72        .name   = "bttv-sub",
  73        .match  = &bttv_sub_bus_match,
  74        .probe  = bttv_sub_probe,
  75        .remove = bttv_sub_remove,
  76};
  77
  78static void release_sub_device(struct device *dev)
  79{
  80        struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
  81        kfree(sub);
  82}
  83
  84int bttv_sub_add_device(struct bttv_core *core, char *name)
  85{
  86        struct bttv_sub_device *sub;
  87        int err;
  88
  89        sub = kzalloc(sizeof(*sub),GFP_KERNEL);
  90        if (NULL == sub)
  91                return -ENOMEM;
  92
  93        sub->core        = core;
  94        sub->dev.parent  = &core->pci->dev;
  95        sub->dev.bus     = &bttv_sub_bus_type;
  96        sub->dev.release = release_sub_device;
  97        dev_set_name(&sub->dev, "%s%d", name, core->nr);
  98
  99        err = device_register(&sub->dev);
 100        if (0 != err) {
 101                kfree(sub);
 102                return err;
 103        }
 104        pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));
 105        list_add_tail(&sub->list,&core->subs);
 106        return 0;
 107}
 108
 109int bttv_sub_del_devices(struct bttv_core *core)
 110{
 111        struct bttv_sub_device *sub, *save;
 112
 113        list_for_each_entry_safe(sub, save, &core->subs, list) {
 114                list_del(&sub->list);
 115                device_unregister(&sub->dev);
 116        }
 117        return 0;
 118}
 119
 120/* ----------------------------------------------------------------------- */
 121/* external: sub-driver register/unregister                                */
 122
 123int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
 124{
 125        sub->drv.bus = &bttv_sub_bus_type;
 126        snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
 127        return driver_register(&sub->drv);
 128}
 129EXPORT_SYMBOL(bttv_sub_register);
 130
 131int bttv_sub_unregister(struct bttv_sub_driver *sub)
 132{
 133        driver_unregister(&sub->drv);
 134        return 0;
 135}
 136EXPORT_SYMBOL(bttv_sub_unregister);
 137
 138/* ----------------------------------------------------------------------- */
 139/* external: gpio access functions                                         */
 140
 141void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
 142{
 143        struct bttv *btv = container_of(core, struct bttv, c);
 144        unsigned long flags;
 145        u32 data;
 146
 147        spin_lock_irqsave(&btv->gpio_lock,flags);
 148        data = btread(BT848_GPIO_OUT_EN);
 149        data = data & ~mask;
 150        data = data | (mask & outbits);
 151        btwrite(data,BT848_GPIO_OUT_EN);
 152        spin_unlock_irqrestore(&btv->gpio_lock,flags);
 153}
 154
 155u32 bttv_gpio_read(struct bttv_core *core)
 156{
 157        struct bttv *btv = container_of(core, struct bttv, c);
 158        u32 value;
 159
 160        value = btread(BT848_GPIO_DATA);
 161        return value;
 162}
 163
 164void bttv_gpio_write(struct bttv_core *core, u32 value)
 165{
 166        struct bttv *btv = container_of(core, struct bttv, c);
 167
 168        btwrite(value,BT848_GPIO_DATA);
 169}
 170
 171void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
 172{
 173        struct bttv *btv = container_of(core, struct bttv, c);
 174        unsigned long flags;
 175        u32 data;
 176
 177        spin_lock_irqsave(&btv->gpio_lock,flags);
 178        data = btread(BT848_GPIO_DATA);
 179        data = data & ~mask;
 180        data = data | (mask & bits);
 181        btwrite(data,BT848_GPIO_DATA);
 182        spin_unlock_irqrestore(&btv->gpio_lock,flags);
 183}
 184
 185/*
 186 * Local variables:
 187 * c-basic-offset: 8
 188 * End:
 189 */
 190