Path: blob/master/drivers/media/video/bt8xx/bttv-gpio.c
10785 views
/*12bttv-gpio.c -- gpio sub drivers34sysfs-based sub driver interface for bttv5mainly intended for gpio access678Copyright (C) 1996,97,98 Ralph Metzler ([email protected])9& Marcus Metzler ([email protected])10(c) 1999-2003 Gerd Knorr <[email protected]>1112This program is free software; you can redistribute it and/or modify13it under the terms of the GNU General Public License as published by14the Free Software Foundation; either version 2 of the License, or15(at your option) any later version.1617This program is distributed in the hope that it will be useful,18but WITHOUT ANY WARRANTY; without even the implied warranty of19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20GNU General Public License for more details.2122You should have received a copy of the GNU General Public License23along with this program; if not, write to the Free Software24Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2526*/2728#include <linux/module.h>29#include <linux/init.h>30#include <linux/delay.h>31#include <linux/device.h>32#include <linux/slab.h>33#include <asm/io.h>3435#include "bttvp.h"3637/* ----------------------------------------------------------------------- */38/* internal: the bttv "bus" */3940static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)41{42struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);43int len = strlen(sub->wanted);4445if (0 == strncmp(dev_name(dev), sub->wanted, len))46return 1;47return 0;48}4950static int bttv_sub_probe(struct device *dev)51{52struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);53struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);5455return sub->probe ? sub->probe(sdev) : -ENODEV;56}5758static int bttv_sub_remove(struct device *dev)59{60struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);61struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);6263if (sub->remove)64sub->remove(sdev);65return 0;66}6768struct bus_type bttv_sub_bus_type = {69.name = "bttv-sub",70.match = &bttv_sub_bus_match,71.probe = bttv_sub_probe,72.remove = bttv_sub_remove,73};7475static void release_sub_device(struct device *dev)76{77struct bttv_sub_device *sub = to_bttv_sub_dev(dev);78kfree(sub);79}8081int bttv_sub_add_device(struct bttv_core *core, char *name)82{83struct bttv_sub_device *sub;84int err;8586sub = kzalloc(sizeof(*sub),GFP_KERNEL);87if (NULL == sub)88return -ENOMEM;8990sub->core = core;91sub->dev.parent = &core->pci->dev;92sub->dev.bus = &bttv_sub_bus_type;93sub->dev.release = release_sub_device;94dev_set_name(&sub->dev, "%s%d", name, core->nr);9596err = device_register(&sub->dev);97if (0 != err) {98kfree(sub);99return err;100}101printk("bttv%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev));102list_add_tail(&sub->list,&core->subs);103return 0;104}105106int bttv_sub_del_devices(struct bttv_core *core)107{108struct bttv_sub_device *sub, *save;109110list_for_each_entry_safe(sub, save, &core->subs, list) {111list_del(&sub->list);112device_unregister(&sub->dev);113}114return 0;115}116117/* ----------------------------------------------------------------------- */118/* external: sub-driver register/unregister */119120int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)121{122sub->drv.bus = &bttv_sub_bus_type;123snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);124return driver_register(&sub->drv);125}126EXPORT_SYMBOL(bttv_sub_register);127128int bttv_sub_unregister(struct bttv_sub_driver *sub)129{130driver_unregister(&sub->drv);131return 0;132}133EXPORT_SYMBOL(bttv_sub_unregister);134135/* ----------------------------------------------------------------------- */136/* external: gpio access functions */137138void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)139{140struct bttv *btv = container_of(core, struct bttv, c);141unsigned long flags;142u32 data;143144spin_lock_irqsave(&btv->gpio_lock,flags);145data = btread(BT848_GPIO_OUT_EN);146data = data & ~mask;147data = data | (mask & outbits);148btwrite(data,BT848_GPIO_OUT_EN);149spin_unlock_irqrestore(&btv->gpio_lock,flags);150}151152u32 bttv_gpio_read(struct bttv_core *core)153{154struct bttv *btv = container_of(core, struct bttv, c);155u32 value;156157value = btread(BT848_GPIO_DATA);158return value;159}160161void bttv_gpio_write(struct bttv_core *core, u32 value)162{163struct bttv *btv = container_of(core, struct bttv, c);164165btwrite(value,BT848_GPIO_DATA);166}167168void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)169{170struct bttv *btv = container_of(core, struct bttv, c);171unsigned long flags;172u32 data;173174spin_lock_irqsave(&btv->gpio_lock,flags);175data = btread(BT848_GPIO_DATA);176data = data & ~mask;177data = data | (mask & bits);178btwrite(data,BT848_GPIO_DATA);179spin_unlock_irqrestore(&btv->gpio_lock,flags);180}181182/*183* Local variables:184* c-basic-offset: 8185* End:186*/187188189