diff options
Diffstat (limited to 'drivers/staging')
565 files changed, 31588 insertions, 46316 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 32bd967f..05e33c7 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,8 +24,6 @@ menuconfig STAGING if STAGING -source "drivers/staging/serial/Kconfig" - source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" @@ -72,8 +70,6 @@ source "drivers/staging/vt6655/Kconfig" source "drivers/staging/vt6656/Kconfig" -source "drivers/staging/vme/Kconfig" - source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" @@ -114,12 +110,12 @@ source "drivers/staging/cptm1217/Kconfig" source "drivers/staging/ste_rmi4/Kconfig" -source "drivers/staging/mei/Kconfig" - source "drivers/staging/nvec/Kconfig" source "drivers/staging/media/Kconfig" +source "drivers/staging/net/Kconfig" + source "drivers/staging/omapdrm/Kconfig" source "drivers/staging/android/Kconfig" @@ -132,4 +128,8 @@ source "drivers/staging/ozwpan/Kconfig" source "drivers/staging/ccg/Kconfig" +source "drivers/staging/ipack/Kconfig" + +source "drivers/staging/gdm72xx/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index eae8a21..a987b3a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,8 +3,8 @@ # fix for build system bug... obj-$(CONFIG_STAGING) += staging.o -obj-y += serial/ obj-y += media/ +obj-y += net/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_USBIP_CORE) += usbip/ @@ -29,6 +29,7 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ +obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ @@ -49,7 +50,6 @@ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ -obj-$(CONFIG_INTEL_MEI) += mei/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ @@ -57,3 +57,4 @@ obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_RAMSTER) += ramster/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ +obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index c706635..0e16b59 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -25,17 +25,9 @@ config ANDROID_LOGGER tristate "Android log driver" default n -config ANDROID_PERSISTENT_RAM - bool - depends on HAVE_MEMBLOCK - select REED_SOLOMON - select REED_SOLOMON_ENC8 - select REED_SOLOMON_DEC8 - config ANDROID_RAM_CONSOLE bool "Android RAM buffer console" - depends on !S390 && !UML && HAVE_MEMBLOCK - select ANDROID_PERSISTENT_RAM + depends on !S390 && !UML && HAVE_MEMBLOCK && PSTORE_RAM=y default n config ANDROID_TIMED_OUTPUT @@ -53,31 +45,15 @@ config ANDROID_LOW_MEMORY_KILLER ---help--- Register processes to be killed when memory is low -config ANDROID_INTF_ALARM +config ANDROID_INTF_ALARM_DEV bool "Android alarm driver" depends on RTC_CLASS default n help Provides non-wakeup and rtc backed wakeup alarms based on rtc or elapsed realtime, and a non-wakeup alarm on the monotonic clock. - Also provides an interface to set the wall time which must be used - for elapsed realtime to work. - -config ANDROID_INTF_ALARM_DEV - bool "Android alarm device" - depends on ANDROID_INTF_ALARM - default y - help - Exports the alarm interface to user-space. + Also exports the alarm interface to user-space. -config ANDROID_ALARM_OLDDRV_COMPAT - bool "Android Alarm compatability with old drivers" - depends on ANDROID_INTF_ALARM - default n - help - Provides preprocessor alias to aid compatability with - older out-of-tree drivers that use the Android Alarm - in-kernel API. This will be removed eventually. endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 045d17b..98711e2 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,10 +1,8 @@ obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o -obj-$(CONFIG_ANDROID_PERSISTENT_RAM) += persistent_ram.o obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o -obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 03efb34..53ce6ec 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -22,19 +22,9 @@ #include <linux/sched.h> #include <linux/spinlock.h> #include <linux/uaccess.h> +#include <linux/alarmtimer.h> #include "android_alarm.h" -/* XXX - Hack out wakelocks, while they are out of tree */ -struct wake_lock { - int i; -}; -#define wake_lock(x) -#define wake_lock_timeout(x, y) -#define wake_unlock(x) -#define WAKE_LOCK_SUSPEND 0 -#define wake_lock_init(x, y, z) ((x)->i = 1) -#define wake_lock_destroy(x) - #define ANDROID_ALARM_PRINT_INFO (1U << 0) #define ANDROID_ALARM_PRINT_IO (1U << 1) #define ANDROID_ALARM_PRINT_INT (1U << 2) @@ -54,19 +44,65 @@ module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ANDROID_ALARM_RTC_WAKEUP_MASK | \ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) -/* support old usespace code */ +/* support old userspace code */ #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) static int alarm_opened; static DEFINE_SPINLOCK(alarm_slock); -static struct wake_lock alarm_wake_lock; +static struct wakeup_source alarm_wake_lock; static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); static uint32_t alarm_pending; static uint32_t alarm_enabled; static uint32_t wait_pending; -static struct android_alarm alarms[ANDROID_ALARM_TYPE_COUNT]; +struct devalarm { + union { + struct hrtimer hrt; + struct alarm alrm; + } u; + enum android_alarm_type type; +}; + +static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; + + +static int is_wakeup(enum android_alarm_type type) +{ + if (type == ANDROID_ALARM_RTC_WAKEUP || + type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP) + return 1; + return 0; +} + + +static void devalarm_start(struct devalarm *alrm, ktime_t exp) +{ + if (is_wakeup(alrm->type)) + alarm_start(&alrm->u.alrm, exp); + else + hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS); +} + + +static int devalarm_try_to_cancel(struct devalarm *alrm) +{ + int ret; + if (is_wakeup(alrm->type)) + ret = alarm_try_to_cancel(&alrm->u.alrm); + else + ret = hrtimer_try_to_cancel(&alrm->u.hrt); + return ret; +} + +static void devalarm_cancel(struct devalarm *alrm) +{ + if (is_wakeup(alrm->type)) + alarm_cancel(&alrm->u.alrm); + else + hrtimer_cancel(&alrm->u.hrt); +} + static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -75,6 +111,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct timespec new_alarm_time; struct timespec new_rtc_time; struct timespec tmp_time; + struct rtc_time new_rtc_tm; + struct rtc_device *rtc_dev; enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); uint32_t alarm_type_mask = 1U << alarm_type; @@ -101,11 +139,11 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case ANDROID_ALARM_CLEAR(0): spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm %d clear\n", alarm_type); - android_alarm_try_to_cancel(&alarms[alarm_type]); + devalarm_try_to_cancel(&alarms[alarm_type]); if (alarm_pending) { alarm_pending &= ~alarm_type_mask; if (!alarm_pending && !wait_pending) - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); @@ -132,8 +170,7 @@ from_old_alarm_set: pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, new_alarm_time.tv_sec, new_alarm_time.tv_nsec); alarm_enabled |= alarm_type_mask; - android_alarm_start_range(&alarms[alarm_type], - timespec_to_ktime(new_alarm_time), + devalarm_start(&alarms[alarm_type], timespec_to_ktime(new_alarm_time)); spin_unlock_irqrestore(&alarm_slock, flags); if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) @@ -144,7 +181,7 @@ from_old_alarm_set: spin_lock_irqsave(&alarm_slock, flags); pr_alarm(IO, "alarm wait\n"); if (!alarm_pending && wait_pending) { - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); wait_pending = 0; } spin_unlock_irqrestore(&alarm_slock, flags); @@ -163,7 +200,13 @@ from_old_alarm_set: rv = -EFAULT; goto err1; } - rv = android_alarm_set_rtc(new_rtc_time); + rtc_time_to_tm(new_rtc_time.tv_sec, &new_rtc_tm); + rtc_dev = alarmtimer_get_rtcdev(); + rv = do_settimeofday(&new_rtc_time); + if (rv < 0) + goto err1; + if (rtc_dev) + rv = rtc_set_time(rtc_dev, &new_rtc_tm); spin_lock_irqsave(&alarm_slock, flags); alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; wake_up(&alarm_wait_queue); @@ -179,8 +222,7 @@ from_old_alarm_set: break; case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: case ANDROID_ALARM_ELAPSED_REALTIME: - tmp_time = - ktime_to_timespec(alarm_get_elapsed_realtime()); + get_monotonic_boottime(&tmp_time); break; case ANDROID_ALARM_TYPE_COUNT: case ANDROID_ALARM_SYSTEMTIME: @@ -224,14 +266,14 @@ static int alarm_release(struct inode *inode, struct file *file) alarm_enabled &= ~alarm_type_mask; } spin_unlock_irqrestore(&alarm_slock, flags); - android_alarm_cancel(&alarms[i]); + devalarm_cancel(&alarms[i]); spin_lock_irqsave(&alarm_slock, flags); } if (alarm_pending | wait_pending) { if (alarm_pending) pr_alarm(INFO, "alarm_release: clear " "pending alarms %x\n", alarm_pending); - wake_unlock(&alarm_wake_lock); + __pm_relax(&alarm_wake_lock); wait_pending = 0; alarm_pending = 0; } @@ -241,15 +283,15 @@ static int alarm_release(struct inode *inode, struct file *file) return 0; } -static void alarm_triggered(struct android_alarm *alarm) +static void devalarm_triggered(struct devalarm *alarm) { unsigned long flags; uint32_t alarm_type_mask = 1U << alarm->type; - pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); + pr_alarm(INT, "devalarm_triggered type %d\n", alarm->type); spin_lock_irqsave(&alarm_slock, flags); if (alarm_enabled & alarm_type_mask) { - wake_lock_timeout(&alarm_wake_lock, 5 * HZ); + __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */ alarm_enabled &= ~alarm_type_mask; alarm_pending |= alarm_type_mask; wake_up(&alarm_wait_queue); @@ -257,6 +299,25 @@ static void alarm_triggered(struct android_alarm *alarm) spin_unlock_irqrestore(&alarm_slock, flags); } + +static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) +{ + struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); + + devalarm_triggered(devalrm); + return HRTIMER_NORESTART; +} + +static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm, + ktime_t now) +{ + struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm); + + devalarm_triggered(devalrm); + return ALARMTIMER_NORESTART; +} + + static const struct file_operations alarm_fops = { .owner = THIS_MODULE, .unlocked_ioctl = alarm_ioctl, @@ -279,17 +340,31 @@ static int __init alarm_dev_init(void) if (err) return err; - for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) - android_alarm_init(&alarms[i], i, alarm_triggered); - wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); + alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, + ALARM_REALTIME, devalarm_alarmhandler); + hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt, + CLOCK_REALTIME, HRTIMER_MODE_ABS); + alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, + ALARM_BOOTTIME, devalarm_alarmhandler); + hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, + CLOCK_BOOTTIME, HRTIMER_MODE_ABS); + hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + + for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { + alarms[i].type = i; + if (!is_wakeup(i)) + alarms[i].u.hrt.function = devalarm_hrthandler; + } + wakeup_source_init(&alarm_wake_lock, "alarm"); return 0; } static void __exit alarm_dev_exit(void) { misc_deregister(&alarm_device); - wake_lock_destroy(&alarm_wake_lock); + wakeup_source_trash(&alarm_wake_lock); } module_init(alarm_dev_init); diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c deleted file mode 100644 index c68950b..0000000 --- a/drivers/staging/android/alarm.c +++ /dev/null @@ -1,601 +0,0 @@ -/* drivers/rtc/alarm.c - * - * Copyright (C) 2007-2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/time.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/miscdevice.h> -#include <linux/platform_device.h> -#include <linux/rtc.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include "android_alarm.h" - -/* XXX - Hack out wakelocks, while they are out of tree */ -struct wake_lock { - int i; -}; -#define wake_lock(x) -#define wake_lock_timeout(x, y) -#define wake_unlock(x) -#define WAKE_LOCK_SUSPEND 0 -#define wake_lock_init(x, y, z) ((x)->i = 1) -#define wake_lock_destroy(x) - -#define ANDROID_ALARM_PRINT_ERROR (1U << 0) -#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) -#define ANDROID_ALARM_PRINT_TSET (1U << 2) -#define ANDROID_ALARM_PRINT_CALL (1U << 3) -#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) -#define ANDROID_ALARM_PRINT_INT (1U << 5) -#define ANDROID_ALARM_PRINT_FLOW (1U << 6) - -static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ - ANDROID_ALARM_PRINT_INIT_STATUS; -module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); - -#define pr_alarm(debug_level_mask, args...) \ - do { \ - if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ - pr_info(args); \ - } \ - } while (0) - -#define ANDROID_ALARM_WAKEUP_MASK ( \ - ANDROID_ALARM_RTC_WAKEUP_MASK | \ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) - -/* support old usespace code */ -#define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ -#define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) - -struct alarm_queue { - struct rb_root alarms; - struct rb_node *first; - struct hrtimer timer; - ktime_t delta; - bool stopped; - ktime_t stopped_time; -}; - -static struct rtc_device *alarm_rtc_dev; -static DEFINE_SPINLOCK(alarm_slock); -static DEFINE_MUTEX(alarm_setrtc_mutex); -static struct wake_lock alarm_rtc_wake_lock; -static struct platform_device *alarm_platform_dev; -struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; -static bool suspended; - -static void update_timer_locked(struct alarm_queue *base, bool head_removed) -{ - struct android_alarm *alarm; - bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || - base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - - if (base->stopped) { - pr_alarm(FLOW, "changed alarm while setting the wall time\n"); - return; - } - - if (is_wakeup && !suspended && head_removed) - wake_unlock(&alarm_rtc_wake_lock); - - if (!base->first) - return; - - alarm = container_of(base->first, struct android_alarm, node); - - pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (is_wakeup && suspended) { - pr_alarm(FLOW, "changed alarm while suspened\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); - return; - } - - hrtimer_try_to_cancel(&base->timer); - base->timer.node.expires = ktime_add(base->delta, alarm->expires); - base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); - hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); -} - -static void alarm_enqueue_locked(struct android_alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - struct rb_node **link = &base->alarms.rb_node; - struct rb_node *parent = NULL; - struct android_alarm *entry; - int leftmost = 1; - bool was_first = false; - - pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, ktime_to_ns(alarm->expires)); - - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - was_first = true; - } - if (!RB_EMPTY_NODE(&alarm->node)) { - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - } - - while (*link) { - parent = *link; - entry = rb_entry(parent, struct android_alarm, node); - /* - * We dont care about collisions. Nodes with - * the same expiry time stay together. - */ - if (alarm->expires.tv64 < entry->expires.tv64) { - link = &(*link)->rb_left; - } else { - link = &(*link)->rb_right; - leftmost = 0; - } - } - if (leftmost) - base->first = &alarm->node; - if (leftmost || was_first) - update_timer_locked(base, was_first); - - rb_link_node(&alarm->node, parent, link); - rb_insert_color(&alarm->node, &base->alarms); -} - -/** - * android_alarm_init - initialize an alarm - * @alarm: the alarm to be initialized - * @type: the alarm type to be used - * @function: alarm callback function - */ -void android_alarm_init(struct android_alarm *alarm, - enum android_alarm_type type, void (*function)(struct android_alarm *)) -{ - RB_CLEAR_NODE(&alarm->node); - alarm->type = type; - alarm->function = function; - - pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); -} - - -/** - * android_alarm_start_range - (re)start an alarm - * @alarm: the alarm to be added - * @start: earliest expiry time - * @end: expiry time - */ -void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, - ktime_t end) -{ - unsigned long flags; - - spin_lock_irqsave(&alarm_slock, flags); - alarm->softexpires = start; - alarm->expires = end; - alarm_enqueue_locked(alarm); - spin_unlock_irqrestore(&alarm_slock, flags); -} - -/** - * android_alarm_try_to_cancel - try to deactivate an alarm - * @alarm: alarm to stop - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - * -1 when the alarm may currently be excuting the callback function and - * cannot be stopped (it may also be inactive) - */ -int android_alarm_try_to_cancel(struct android_alarm *alarm) -{ - struct alarm_queue *base = &alarms[alarm->type]; - unsigned long flags; - bool first = false; - int ret = 0; - - spin_lock_irqsave(&alarm_slock, flags); - if (!RB_EMPTY_NODE(&alarm->node)) { - pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires)); - ret = 1; - if (base->first == &alarm->node) { - base->first = rb_next(&alarm->node); - first = true; - } - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - if (first) - update_timer_locked(base, true); - } else - pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", - alarm->type, alarm->function); - spin_unlock_irqrestore(&alarm_slock, flags); - if (!ret && hrtimer_callback_running(&base->timer)) - ret = -1; - return ret; -} - -/** - * android_alarm_cancel - cancel an alarm and wait for the handler to finish. - * @alarm: the alarm to be cancelled - * - * Returns: - * 0 when the alarm was not active - * 1 when the alarm was active - */ -int android_alarm_cancel(struct android_alarm *alarm) -{ - for (;;) { - int ret = android_alarm_try_to_cancel(alarm); - if (ret >= 0) - return ret; - cpu_relax(); - } -} - -/** - * alarm_set_rtc - set the kernel and rtc walltime - * @new_time: timespec value containing the new time - */ -int android_alarm_set_rtc(struct timespec new_time) -{ - int i; - int ret; - unsigned long flags; - struct rtc_time rtc_new_rtc_time; - struct timespec tmp_time; - - rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); - - pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", - new_time.tv_sec, new_time.tv_nsec, - rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, - rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, - rtc_new_rtc_time.tm_mday, - rtc_new_rtc_time.tm_year + 1900); - - mutex_lock(&alarm_setrtc_mutex); - spin_lock_irqsave(&alarm_slock, flags); - wake_lock(&alarm_rtc_wake_lock); - getnstimeofday(&tmp_time); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_try_to_cancel(&alarms[i].timer); - alarms[i].stopped = true; - alarms[i].stopped_time = timespec_to_ktime(tmp_time); - } - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, - timespec_to_ktime(timespec_sub(tmp_time, new_time))); - spin_unlock_irqrestore(&alarm_slock, flags); - ret = do_settimeofday(&new_time); - spin_lock_irqsave(&alarm_slock, flags); - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - alarms[i].stopped = false; - update_timer_locked(&alarms[i], false); - } - spin_unlock_irqrestore(&alarm_slock, flags); - if (ret < 0) { - pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); - goto err; - } - if (!alarm_rtc_dev) { - pr_alarm(ERROR, - "alarm_set_rtc: no RTC, time will be lost on reboot\n"); - goto err; - } - ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); - if (ret < 0) - pr_alarm(ERROR, "alarm_set_rtc: " - "Failed to set RTC, time will be lost on reboot\n"); -err: - wake_unlock(&alarm_rtc_wake_lock); - mutex_unlock(&alarm_setrtc_mutex); - return ret; -} - -/** - * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format - * - * returns the time in ktime_t format - */ -ktime_t alarm_get_elapsed_realtime(void) -{ - ktime_t now; - unsigned long flags; - struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; - - spin_lock_irqsave(&alarm_slock, flags); - now = base->stopped ? base->stopped_time : ktime_get_real(); - now = ktime_sub(now, base->delta); - spin_unlock_irqrestore(&alarm_slock, flags); - return now; -} - -static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) -{ - struct alarm_queue *base; - struct android_alarm *alarm; - unsigned long flags; - ktime_t now; - - spin_lock_irqsave(&alarm_slock, flags); - - base = container_of(timer, struct alarm_queue, timer); - now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); - now = ktime_sub(now, base->delta); - - pr_alarm(INT, "alarm_timer_triggered type %ld at %lld\n", - base - alarms, ktime_to_ns(now)); - - while (base->first) { - alarm = container_of(base->first, struct android_alarm, node); - if (alarm->softexpires.tv64 > now.tv64) { - pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", - alarm->function, ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - break; - } - base->first = rb_next(&alarm->node); - rb_erase(&alarm->node, &base->alarms); - RB_CLEAR_NODE(&alarm->node); - pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", - alarm->type, alarm->function, - ktime_to_ns(alarm->expires), - ktime_to_ns(alarm->softexpires)); - spin_unlock_irqrestore(&alarm_slock, flags); - alarm->function(alarm); - spin_lock_irqsave(&alarm_slock, flags); - } - if (!base->first) - pr_alarm(FLOW, "no more alarms of type %ld\n", base - alarms); - update_timer_locked(base, true); - spin_unlock_irqrestore(&alarm_slock, flags); - return HRTIMER_NORESTART; -} - -static void alarm_triggered_func(void *p) -{ - struct rtc_device *rtc = alarm_rtc_dev; - if (!(rtc->irq_data & RTC_AF)) - return; - pr_alarm(INT, "rtc alarm triggered\n"); - wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); -} - -static int alarm_suspend(struct platform_device *pdev, pm_message_t state) -{ - int err = 0; - unsigned long flags; - struct rtc_wkalrm rtc_alarm; - struct rtc_time rtc_current_rtc_time; - unsigned long rtc_current_time; - unsigned long rtc_alarm_time; - struct timespec rtc_delta; - struct timespec wall_time; - struct alarm_queue *wakeup_queue = NULL; - struct alarm_queue *tmp_queue = NULL; - - pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = true; - spin_unlock_irqrestore(&alarm_slock, flags); - - hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); - hrtimer_cancel(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); - - tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; - if (tmp_queue->first) - wakeup_queue = tmp_queue; - tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; - if (tmp_queue->first && (!wakeup_queue || - hrtimer_get_expires(&tmp_queue->timer).tv64 < - hrtimer_get_expires(&wakeup_queue->timer).tv64)) - wakeup_queue = tmp_queue; - if (wakeup_queue) { - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - getnstimeofday(&wall_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - set_normalized_timespec(&rtc_delta, - wall_time.tv_sec - rtc_current_time, - wall_time.tv_nsec); - - rtc_alarm_time = timespec_sub(ktime_to_timespec( - hrtimer_get_expires(&wakeup_queue->timer)), - rtc_delta).tv_sec; - - rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); - rtc_alarm.enabled = 1; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); - rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); - pr_alarm(SUSPEND, - "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", - rtc_alarm_time, rtc_current_time, - rtc_delta.tv_sec, rtc_delta.tv_nsec); - if (rtc_current_time + 1 >= rtc_alarm_time) { - pr_alarm(SUSPEND, "alarm about to go off\n"); - memset(&rtc_alarm, 0, sizeof(rtc_alarm)); - rtc_alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], - false); - update_timer_locked(&alarms[ - ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); - err = -EBUSY; - spin_unlock_irqrestore(&alarm_slock, flags); - } - } - return err; -} - -static int alarm_resume(struct platform_device *pdev) -{ - struct rtc_wkalrm alarm; - unsigned long flags; - - pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); - - memset(&alarm, 0, sizeof(alarm)); - alarm.enabled = 0; - rtc_set_alarm(alarm_rtc_dev, &alarm); - - spin_lock_irqsave(&alarm_slock, flags); - suspended = false; - update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); - update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], - false); - spin_unlock_irqrestore(&alarm_slock, flags); - - return 0; -} - -static struct rtc_task alarm_rtc_task = { - .func = alarm_triggered_func -}; - -static int rtc_alarm_add_device(struct device *dev, - struct class_interface *class_intf) -{ - int err; - struct rtc_device *rtc = to_rtc_device(dev); - - mutex_lock(&alarm_setrtc_mutex); - - if (alarm_rtc_dev) { - err = -EBUSY; - goto err1; - } - - alarm_platform_dev = - platform_device_register_simple("alarm", -1, NULL, 0); - if (IS_ERR(alarm_platform_dev)) { - err = PTR_ERR(alarm_platform_dev); - goto err2; - } - err = rtc_irq_register(rtc, &alarm_rtc_task); - if (err) - goto err3; - alarm_rtc_dev = rtc; - pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); - mutex_unlock(&alarm_setrtc_mutex); - - return 0; - -err3: - platform_device_unregister(alarm_platform_dev); -err2: -err1: - mutex_unlock(&alarm_setrtc_mutex); - return err; -} - -static void rtc_alarm_remove_device(struct device *dev, - struct class_interface *class_intf) -{ - if (dev == &alarm_rtc_dev->dev) { - pr_alarm(INIT_STATUS, "lost rtc device for alarms"); - rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); - platform_device_unregister(alarm_platform_dev); - alarm_rtc_dev = NULL; - } -} - -static struct class_interface rtc_alarm_interface = { - .add_dev = &rtc_alarm_add_device, - .remove_dev = &rtc_alarm_remove_device, -}; - -static struct platform_driver alarm_driver = { - .suspend = alarm_suspend, - .resume = alarm_resume, - .driver = { - .name = "alarm" - } -}; - -static int __init alarm_late_init(void) -{ - unsigned long flags; - struct timespec tmp_time, system_time; - - /* this needs to run after the rtc is read at boot */ - spin_lock_irqsave(&alarm_slock, flags); - /* We read the current rtc and system time so we can later calulate - * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == - * (rtc - (boot_rtc - boot_systemtime)) - */ - getnstimeofday(&tmp_time); - ktime_get_ts(&system_time); - alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = - alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = - timespec_to_ktime(timespec_sub(tmp_time, system_time)); - - spin_unlock_irqrestore(&alarm_slock, flags); - return 0; -} - -static int __init alarm_driver_init(void) -{ - int err; - int i; - - for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { - hrtimer_init(&alarms[i].timer, - CLOCK_REALTIME, HRTIMER_MODE_ABS); - alarms[i].timer.function = alarm_timer_triggered; - } - hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; - err = platform_driver_register(&alarm_driver); - if (err < 0) - goto err1; - wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); - rtc_alarm_interface.class = rtc_class; - err = class_interface_register(&rtc_alarm_interface); - if (err < 0) - goto err2; - - return 0; - -err2: - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -err1: - return err; -} - -static void __exit alarm_exit(void) -{ - class_interface_unregister(&rtc_alarm_interface); - wake_lock_destroy(&alarm_rtc_wake_lock); - platform_driver_unregister(&alarm_driver); -} - -late_initcall(alarm_late_init); -module_init(alarm_driver_init); -module_exit(alarm_exit); - diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index 6eecbde..d0cafd6 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -33,65 +33,6 @@ enum android_alarm_type { /* ANDROID_ALARM_TIME_CHANGE = 16 */ }; -#ifdef __KERNEL__ - -#include <linux/ktime.h> -#include <linux/rbtree.h> - -/* - * The alarm interface is similar to the hrtimer interface but adds support - * for wakeup from suspend. It also adds an elapsed realtime clock that can - * be used for periodic timers that need to keep runing while the system is - * suspended and not be disrupted when the wall time is set. - */ - -/** - * struct alarm - the basic alarm structure - * @node: red black tree node for time ordered insertion - * @type: alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup. - * @softexpires: the absolute earliest expiry time of the alarm. - * @expires: the absolute expiry time. - * @function: alarm expiry callback function - * - * The alarm structure must be initialized by alarm_init() - * - */ - -struct android_alarm { - struct rb_node node; - enum android_alarm_type type; - ktime_t softexpires; - ktime_t expires; - void (*function)(struct android_alarm *); -}; - -void android_alarm_init(struct android_alarm *alarm, - enum android_alarm_type type, void (*function)(struct android_alarm *)); -void android_alarm_start_range(struct android_alarm *alarm, ktime_t start, - ktime_t end); -int android_alarm_try_to_cancel(struct android_alarm *alarm); -int android_alarm_cancel(struct android_alarm *alarm); -ktime_t alarm_get_elapsed_realtime(void); - -/* set rtc while preserving elapsed realtime */ -int android_alarm_set_rtc(const struct timespec ts); - -#ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT -/* - * Some older drivers depend on the old API, - * so provide compatability macros for now. - */ -#define alarm android_alarm -#define alarm_init(x, y, z) android_alarm_init(x, y, z) -#define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z) -#define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x) -#define alarm_cancel(x) android_alarm_cancel(x) -#define alarm_set_rtc(x) android_alarm_set_rtc(x) -#endif - - -#endif - enum android_alarm_return_flags { ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h index 25ab6f2..2f7d195 100644 --- a/drivers/staging/android/binder.h +++ b/drivers/staging/android/binder.h @@ -53,17 +53,17 @@ struct flat_binder_object { /* 8 bytes of data. */ union { - void *binder; /* local object */ + void __user *binder; /* local object */ signed long handle; /* remote object */ }; /* extra data associated with local object */ - void *cookie; + void __user *cookie; }; /* * On 64-bit platforms where user code may run in 32-bits the driver must - * translate the buffer (and local binder) addresses apropriately. + * translate the buffer (and local binder) addresses appropriately. */ struct binder_write_read { @@ -139,9 +139,9 @@ struct binder_transaction_data { union { struct { /* transaction data */ - const void *buffer; + const void __user *buffer; /* offsets from buffer to flat_binder_object structs */ - const void *offsets; + const void __user *offsets; } ptr; uint8_t buf[8]; } data; diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c index ea69b6a..b2e71c6 100644 --- a/drivers/staging/android/logger.c +++ b/drivers/staging/android/logger.c @@ -25,6 +25,7 @@ #include <linux/poll.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/vmalloc.h> #include "logger.h" #include <asm/ioctls.h> @@ -45,8 +46,12 @@ struct logger_log { size_t w_off; /* current write head offset */ size_t head; /* new readers start here */ size_t size; /* size of the log */ + struct list_head logs; /* list of log channels (myself)*/ }; +static LIST_HEAD(log_list); + + /* * struct logger_reader - a logging device open for reading * @@ -60,9 +65,9 @@ struct logger_reader { }; /* logger_offset - returns index 'n' into the log via (optimized) modulus */ -size_t logger_offset(struct logger_log *log, size_t n) +static size_t logger_offset(struct logger_log *log, size_t n) { - return n & (log->size-1); + return n & (log->size - 1); } @@ -348,7 +353,7 @@ static ssize_t do_write_log_from_user(struct logger_log *log, * writev(), and aio_write(). Writes are our fast path, and we try to optimize * them above all else. */ -ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, +static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t ppos) { struct logger_log *log = file_get_log(iocb->ki_filp); @@ -408,7 +413,15 @@ ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, return ret; } -static struct logger_log *get_log_from_minor(int); +static struct logger_log *get_log_from_minor(int minor) +{ + struct logger_log *log; + + list_for_each_entry(log, &log_list, logs) + if (log->misc.minor == minor) + return log; + return NULL; +} /* * logger_open - the log's open() file operation @@ -565,80 +578,84 @@ static const struct file_operations logger_fops = { }; /* - * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which - * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than - * LONG_MAX minus LOGGER_ENTRY_MAX_LEN. + * Log size must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, + * and less than LONG_MAX minus LOGGER_ENTRY_MAX_LEN. */ -#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -static unsigned char _buf_ ## VAR[SIZE]; \ -static struct logger_log VAR = { \ - .buffer = _buf_ ## VAR, \ - .misc = { \ - .minor = MISC_DYNAMIC_MINOR, \ - .name = NAME, \ - .fops = &logger_fops, \ - .parent = NULL, \ - }, \ - .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ - .readers = LIST_HEAD_INIT(VAR .readers), \ - .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ - .w_off = 0, \ - .head = 0, \ - .size = SIZE, \ -}; +static int __init create_log(char *log_name, int size) +{ + int ret = 0; + struct logger_log *log; + unsigned char *buffer; -DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024) -DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024) -DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024) + buffer = vmalloc(size); + if (buffer == NULL) + return -ENOMEM; -static struct logger_log *get_log_from_minor(int minor) -{ - if (log_main.misc.minor == minor) - return &log_main; - if (log_events.misc.minor == minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; - if (log_system.misc.minor == minor) - return &log_system; - return NULL; -} + log = kzalloc(sizeof(struct logger_log), GFP_KERNEL); + if (log == NULL) { + ret = -ENOMEM; + goto out_free_buffer; + } + log->buffer = buffer; -static int __init init_log(struct logger_log *log) -{ - int ret; + log->misc.minor = MISC_DYNAMIC_MINOR; + log->misc.name = kstrdup(log_name, GFP_KERNEL); + if (log->misc.name == NULL) { + ret = -ENOMEM; + goto out_free_log; + } + + log->misc.fops = &logger_fops; + log->misc.parent = NULL; + init_waitqueue_head(&log->wq); + INIT_LIST_HEAD(&log->readers); + mutex_init(&log->mutex); + log->w_off = 0; + log->head = 0; + log->size = size; + + INIT_LIST_HEAD(&log->logs); + list_add_tail(&log->logs, &log_list); + + /* finally, initialize the misc device for this log */ ret = misc_register(&log->misc); if (unlikely(ret)) { printk(KERN_ERR "logger: failed to register misc " "device for log '%s'!\n", log->misc.name); - return ret; + goto out_free_log; } printk(KERN_INFO "logger: created %luK log '%s'\n", (unsigned long) log->size >> 10, log->misc.name); return 0; + +out_free_log: + kfree(log); + +out_free_buffer: + vfree(buffer); + return ret; } static int __init logger_init(void) { int ret; - ret = init_log(&log_main); + ret = create_log(LOGGER_LOG_MAIN, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_events); + ret = create_log(LOGGER_LOG_EVENTS, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_radio); + ret = create_log(LOGGER_LOG_RADIO, 256*1024); if (unlikely(ret)) goto out; - ret = init_log(&log_system); + ret = create_log(LOGGER_LOG_SYSTEM, 256*1024); if (unlikely(ret)) goto out; diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c deleted file mode 100644 index 8d8c1e3..0000000 --- a/drivers/staging/android/persistent_ram.c +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (C) 2012 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include <linux/device.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/list.h> -#include <linux/memblock.h> -#include <linux/rslib.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include "persistent_ram.h" - -struct persistent_ram_buffer { - uint32_t sig; - atomic_t start; - atomic_t size; - uint8_t data[0]; -}; - -#define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */ - -static __initdata LIST_HEAD(persistent_ram_list); - -static inline size_t buffer_size(struct persistent_ram_zone *prz) -{ - return atomic_read(&prz->buffer->size); -} - -static inline size_t buffer_start(struct persistent_ram_zone *prz) -{ - return atomic_read(&prz->buffer->start); -} - -/* increase and wrap the start pointer, returning the old value */ -static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) -{ - int old; - int new; - - do { - old = atomic_read(&prz->buffer->start); - new = old + a; - while (unlikely(new > prz->buffer_size)) - new -= prz->buffer_size; - } while (atomic_cmpxchg(&prz->buffer->start, old, new) != old); - - return old; -} - -/* increase the size counter until it hits the max size */ -static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) -{ - size_t old; - size_t new; - - if (atomic_read(&prz->buffer->size) == prz->buffer_size) - return; - - do { - old = atomic_read(&prz->buffer->size); - new = old + a; - if (new > prz->buffer_size) - new = prz->buffer_size; - } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); -} - -/* increase the size counter, retuning an error if it hits the max size */ -static inline ssize_t buffer_size_add_clamp(struct persistent_ram_zone *prz, - size_t a) -{ - size_t old; - size_t new; - - do { - old = atomic_read(&prz->buffer->size); - new = old + a; - if (new > prz->buffer_size) - return -ENOMEM; - } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); - - return 0; -} - -static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, - uint8_t *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[prz->ecc_size]; - - /* Initialize the parity buffer */ - memset(par, 0, sizeof(par)); - encode_rs8(prz->rs_decoder, data, len, par, 0); - for (i = 0; i < prz->ecc_size; i++) - ecc[i] = par[i]; -} - -static int persistent_ram_decode_rs8(struct persistent_ram_zone *prz, - void *data, size_t len, uint8_t *ecc) -{ - int i; - uint16_t par[prz->ecc_size]; - - for (i = 0; i < prz->ecc_size; i++) - par[i] = ecc[i]; - return decode_rs8(prz->rs_decoder, data, par, len, - NULL, 0, NULL, 0, NULL); -} - -static void notrace persistent_ram_update_ecc(struct persistent_ram_zone *prz, - unsigned int start, unsigned int count) -{ - struct persistent_ram_buffer *buffer = prz->buffer; - uint8_t *buffer_end = buffer->data + prz->buffer_size; - uint8_t *block; - uint8_t *par; - int ecc_block_size = prz->ecc_block_size; - int ecc_size = prz->ecc_size; - int size = prz->ecc_block_size; - - if (!prz->ecc) - return; - - block = buffer->data + (start & ~(ecc_block_size - 1)); - par = prz->par_buffer + (start / ecc_block_size) * prz->ecc_size; - - do { - if (block + ecc_block_size > buffer_end) - size = buffer_end - block; - persistent_ram_encode_rs8(prz, block, size, par); - block += ecc_block_size; - par += ecc_size; - } while (block < buffer->data + start + count); -} - -static void persistent_ram_update_header_ecc(struct persistent_ram_zone *prz) -{ - struct persistent_ram_buffer *buffer = prz->buffer; - - if (!prz->ecc) - return; - - persistent_ram_encode_rs8(prz, (uint8_t *)buffer, sizeof(*buffer), - prz->par_header); -} - -static void persistent_ram_ecc_old(struct persistent_ram_zone *prz) -{ - struct persistent_ram_buffer *buffer = prz->buffer; - uint8_t *block; - uint8_t *par; - - if (!prz->ecc) - return; - - block = buffer->data; - par = prz->par_buffer; - while (block < buffer->data + buffer_size(prz)) { - int numerr; - int size = prz->ecc_block_size; - if (block + size > buffer->data + prz->buffer_size) - size = buffer->data + prz->buffer_size - block; - numerr = persistent_ram_decode_rs8(prz, block, size, par); - if (numerr > 0) { - pr_devel("persistent_ram: error in block %p, %d\n", - block, numerr); - prz->corrected_bytes += numerr; - } else if (numerr < 0) { - pr_devel("persistent_ram: uncorrectable error in block %p\n", - block); - prz->bad_blocks++; - } - block += prz->ecc_block_size; - par += prz->ecc_size; - } -} - -static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, - size_t buffer_size) -{ - int numerr; - struct persistent_ram_buffer *buffer = prz->buffer; - int ecc_blocks; - - if (!prz->ecc) - return 0; - - prz->ecc_block_size = 128; - prz->ecc_size = 16; - prz->ecc_symsize = 8; - prz->ecc_poly = 0x11d; - - ecc_blocks = DIV_ROUND_UP(prz->buffer_size, prz->ecc_block_size); - prz->buffer_size -= (ecc_blocks + 1) * prz->ecc_size; - - if (prz->buffer_size > buffer_size) { - pr_err("persistent_ram: invalid size %zu, non-ecc datasize %zu\n", - buffer_size, prz->buffer_size); - return -EINVAL; - } - - prz->par_buffer = buffer->data + prz->buffer_size; - prz->par_header = prz->par_buffer + ecc_blocks * prz->ecc_size; - - /* - * first consecutive root is 0 - * primitive element to generate roots = 1 - */ - prz->rs_decoder = init_rs(prz->ecc_symsize, prz->ecc_poly, 0, 1, - prz->ecc_size); - if (prz->rs_decoder == NULL) { - pr_info("persistent_ram: init_rs failed\n"); - return -EINVAL; - } - - prz->corrected_bytes = 0; - prz->bad_blocks = 0; - - numerr = persistent_ram_decode_rs8(prz, buffer, sizeof(*buffer), - prz->par_header); - if (numerr > 0) { - pr_info("persistent_ram: error in header, %d\n", numerr); - prz->corrected_bytes += numerr; - } else if (numerr < 0) { - pr_info("persistent_ram: uncorrectable error in header\n"); - prz->bad_blocks++; - } - - return 0; -} - -ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz, - char *str, size_t len) -{ - ssize_t ret; - - if (prz->corrected_bytes || prz->bad_blocks) - ret = snprintf(str, len, "" - "\n%d Corrected bytes, %d unrecoverable blocks\n", - prz->corrected_bytes, prz->bad_blocks); - else - ret = snprintf(str, len, "\nNo errors detected\n"); - - return ret; -} - -static void notrace persistent_ram_update(struct persistent_ram_zone *prz, - const void *s, unsigned int start, unsigned int count) -{ - struct persistent_ram_buffer *buffer = prz->buffer; - memcpy(buffer->data + start, s, count); - persistent_ram_update_ecc(prz, start, count); -} - -static void __init -persistent_ram_save_old(struct persistent_ram_zone *prz) -{ - struct persistent_ram_buffer *buffer = prz->buffer; - size_t size = buffer_size(prz); - size_t start = buffer_start(prz); - char *dest; - - persistent_ram_ecc_old(prz); - - dest = kmalloc(size, GFP_KERNEL); - if (dest == NULL) { - pr_err("persistent_ram: failed to allocate buffer\n"); - return; - } - - prz->old_log = dest; - prz->old_log_size = size; - memcpy(prz->old_log, &buffer->data[start], size - start); - memcpy(prz->old_log + size - start, &buffer->data[0], start); -} - -int notrace persistent_ram_write(struct persistent_ram_zone *prz, - const void *s, unsigned int count) -{ - int rem; - int c = count; - size_t start; - - if (unlikely(c > prz->buffer_size)) { - s += c - prz->buffer_size; - c = prz->buffer_size; - } - - buffer_size_add_clamp(prz, c); - - start = buffer_start_add(prz, c); - - rem = prz->buffer_size - start; - if (unlikely(rem < c)) { - persistent_ram_update(prz, s, start, rem); - s += rem; - c -= rem; - start = 0; - } - persistent_ram_update(prz, s, start, c); - - persistent_ram_update_header_ecc(prz); - - return count; -} - -size_t persistent_ram_old_size(struct persistent_ram_zone *prz) -{ - return prz->old_log_size; -} - -void *persistent_ram_old(struct persistent_ram_zone *prz) -{ - return prz->old_log; -} - -void persistent_ram_free_old(struct persistent_ram_zone *prz) -{ - kfree(prz->old_log); - prz->old_log = NULL; - prz->old_log_size = 0; -} - -static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, - struct persistent_ram_zone *prz) -{ - struct page **pages; - phys_addr_t page_start; - unsigned int page_count; - pgprot_t prot; - unsigned int i; - - page_start = start - offset_in_page(start); - page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE); - - prot = pgprot_noncached(PAGE_KERNEL); - - pages = kmalloc(sizeof(struct page *) * page_count, GFP_KERNEL); - if (!pages) { - pr_err("%s: Failed to allocate array for %u pages\n", __func__, - page_count); - return -ENOMEM; - } - - for (i = 0; i < page_count; i++) { - phys_addr_t addr = page_start + i * PAGE_SIZE; - pages[i] = pfn_to_page(addr >> PAGE_SHIFT); - } - prz->vaddr = vmap(pages, page_count, VM_MAP, prot); - kfree(pages); - if (!prz->vaddr) { - pr_err("%s: Failed to map %u pages\n", __func__, page_count); - return -ENOMEM; - } - - prz->buffer = prz->vaddr + offset_in_page(start); - prz->buffer_size = size - sizeof(struct persistent_ram_buffer); - - return 0; -} - -static int __init persistent_ram_buffer_init(const char *name, - struct persistent_ram_zone *prz) -{ - int i; - struct persistent_ram *ram; - struct persistent_ram_descriptor *desc; - phys_addr_t start; - - list_for_each_entry(ram, &persistent_ram_list, node) { - start = ram->start; - for (i = 0; i < ram->num_descs; i++) { - desc = &ram->descs[i]; - if (!strcmp(desc->name, name)) - return persistent_ram_buffer_map(start, - desc->size, prz); - start += desc->size; - } - } - - return -EINVAL; -} - -static __init -struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) -{ - struct persistent_ram_zone *prz; - int ret = -ENOMEM; - - prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); - if (!prz) { - pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - goto err; - } - - INIT_LIST_HEAD(&prz->node); - - ret = persistent_ram_buffer_init(dev_name(dev), prz); - if (ret) { - pr_err("persistent_ram: failed to initialize buffer\n"); - goto err; - } - - prz->ecc = ecc; - ret = persistent_ram_init_ecc(prz, prz->buffer_size); - if (ret) - goto err; - - if (prz->buffer->sig == PERSISTENT_RAM_SIG) { - if (buffer_size(prz) > prz->buffer_size || - buffer_start(prz) > buffer_size(prz)) - pr_info("persistent_ram: found existing invalid buffer," - " size %ld, start %ld\n", - buffer_size(prz), buffer_start(prz)); - else { - pr_info("persistent_ram: found existing buffer," - " size %ld, start %ld\n", - buffer_size(prz), buffer_start(prz)); - persistent_ram_save_old(prz); - } - } else { - pr_info("persistent_ram: no valid data in buffer" - " (sig = 0x%08x)\n", prz->buffer->sig); - } - - prz->buffer->sig = PERSISTENT_RAM_SIG; - atomic_set(&prz->buffer->start, 0); - atomic_set(&prz->buffer->size, 0); - - return prz; -err: - kfree(prz); - return ERR_PTR(ret); -} - -struct persistent_ram_zone * __init -persistent_ram_init_ringbuffer(struct device *dev, bool ecc) -{ - return __persistent_ram_init(dev, ecc); -} - -int __init persistent_ram_early_init(struct persistent_ram *ram) -{ - int ret; - - ret = memblock_reserve(ram->start, ram->size); - if (ret) { - pr_err("Failed to reserve persistent memory from %08lx-%08lx\n", - (long)ram->start, (long)(ram->start + ram->size - 1)); - return ret; - } - - list_add_tail(&ram->node, &persistent_ram_list); - - pr_info("Initialized persistent memory from %08lx-%08lx\n", - (long)ram->start, (long)(ram->start + ram->size - 1)); - - return 0; -} diff --git a/drivers/staging/android/persistent_ram.h b/drivers/staging/android/persistent_ram.h deleted file mode 100644 index f41e208..0000000 --- a/drivers/staging/android/persistent_ram.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __LINUX_PERSISTENT_RAM_H__ -#define __LINUX_PERSISTENT_RAM_H__ - -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/types.h> - -struct persistent_ram_buffer; - -struct persistent_ram_descriptor { - const char *name; - phys_addr_t size; -}; - -struct persistent_ram { - phys_addr_t start; - phys_addr_t size; - - int num_descs; - struct persistent_ram_descriptor *descs; - - struct list_head node; -}; - -struct persistent_ram_zone { - struct list_head node; - void *vaddr; - struct persistent_ram_buffer *buffer; - size_t buffer_size; - - /* ECC correction */ - bool ecc; - char *par_buffer; - char *par_header; - struct rs_control *rs_decoder; - int corrected_bytes; - int bad_blocks; - int ecc_block_size; - int ecc_size; - int ecc_symsize; - int ecc_poly; - - char *old_log; - size_t old_log_size; - size_t old_log_footer_size; - bool early; -}; - -int persistent_ram_early_init(struct persistent_ram *ram); - -struct persistent_ram_zone *persistent_ram_init_ringbuffer(struct device *dev, - bool ecc); - -int persistent_ram_write(struct persistent_ram_zone *prz, const void *s, - unsigned int count); - -size_t persistent_ram_old_size(struct persistent_ram_zone *prz); -void *persistent_ram_old(struct persistent_ram_zone *prz); -void persistent_ram_free_old(struct persistent_ram_zone *prz); -ssize_t persistent_ram_ecc_string(struct persistent_ram_zone *prz, - char *str, size_t len); - -#endif diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c index ce140ff..82323bb 100644 --- a/drivers/staging/android/ram_console.c +++ b/drivers/staging/android/ram_console.c @@ -21,7 +21,7 @@ #include <linux/string.h> #include <linux/uaccess.h> #include <linux/io.h> -#include "persistent_ram.h" +#include <linux/pstore_ram.h> #include "ram_console.h" static struct persistent_ram_zone *ram_console_zone; diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c index f373422..38d930c 100644 --- a/drivers/staging/android/timed_output.c +++ b/drivers/staging/android/timed_output.c @@ -99,6 +99,7 @@ EXPORT_SYMBOL_GPL(timed_output_dev_register); void timed_output_dev_unregister(struct timed_output_dev *tdev) { + tdev->enable(tdev, 0); device_remove_file(tdev->dev, &dev_attr_enable); device_destroy(timed_output_class, MKDEV(0, tdev->index)); dev_set_drvdata(tdev->dev, NULL); diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 20cca24..aa51d17 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -7,168 +7,145 @@ #define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 #include "Debug.h" -struct _LEADER -{ - USHORT Vcid; - USHORT PLength; - UCHAR Status; +struct _LEADER { + USHORT Vcid; + USHORT PLength; + UCHAR Status; UCHAR Unused[3]; -}__attribute__((packed)); -typedef struct _LEADER LEADER,*PLEADER; +} __packed; +typedef struct _LEADER LEADER, *PLEADER; -struct _PACKETTOSEND -{ +struct _PACKETTOSEND { LEADER Leader; UCHAR ucPayload; -}__attribute__((packed)); +} __packed; typedef struct _PACKETTOSEND PACKETTOSEND, *PPACKETTOSEND; - -struct _CONTROL_PACKET -{ +struct _CONTROL_PACKET { PVOID ControlBuff; UINT ControlBuffLen; - struct _CONTROL_PACKET* next; -}__attribute__((packed)); -typedef struct _CONTROL_PACKET CONTROL_PACKET,*PCONTROL_PACKET; - + struct _CONTROL_PACKET *next; +} __packed; +typedef struct _CONTROL_PACKET CONTROL_PACKET, *PCONTROL_PACKET; -struct link_request -{ +struct link_request { LEADER Leader; UCHAR szData[4]; -}__attribute__((packed)); +} __packed; typedef struct link_request LINK_REQUEST, *PLINK_REQUEST; - -//classification extension is added -typedef struct _ADD_CONNECTION -{ - ULONG SrcIpAddressCount; - ULONG SrcIpAddress[MAX_CONNECTIONS]; - ULONG SrcIpMask[MAX_CONNECTIONS]; - - ULONG DestIpAddressCount; - ULONG DestIpAddress[MAX_CONNECTIONS]; - ULONG DestIpMask[MAX_CONNECTIONS]; - - USHORT SrcPortBegin; - USHORT SrcPortEnd; - - USHORT DestPortBegin; - USHORT DestPortEnd; - - UCHAR SrcTOS; - UCHAR SrcProtocol; -} ADD_CONNECTION,*PADD_CONNECTION; - - -typedef struct _CLASSIFICATION_RULE -{ - UCHAR ucIPSrcAddrLen; - UCHAR ucIPSrcAddr[32]; - UCHAR ucIPDestAddrLen; - UCHAR ucIPDestAddr[32]; - UCHAR ucSrcPortRangeLen; - UCHAR ucSrcPortRange[4]; - UCHAR ucDestPortRangeLen; - UCHAR ucDestPortRange[4]; - USHORT usVcid; -} CLASSIFICATION_RULE,*PCLASSIFICATION_RULE; - -typedef struct _CLASSIFICATION_ONLY -{ - USHORT usVcid; - ULONG DestIpAddress; - ULONG DestIpMask; - USHORT usPortLo; - USHORT usPortHi; - BOOLEAN bIpVersion; - UCHAR ucDestinationAddress[16]; +/* classification extension is added */ +typedef struct _ADD_CONNECTION { + ULONG SrcIpAddressCount; + ULONG SrcIpAddress[MAX_CONNECTIONS]; + ULONG SrcIpMask[MAX_CONNECTIONS]; + + ULONG DestIpAddressCount; + ULONG DestIpAddress[MAX_CONNECTIONS]; + ULONG DestIpMask[MAX_CONNECTIONS]; + + USHORT SrcPortBegin; + USHORT SrcPortEnd; + + USHORT DestPortBegin; + USHORT DestPortEnd; + + UCHAR SrcTOS; + UCHAR SrcProtocol; +} ADD_CONNECTION, *PADD_CONNECTION; + +typedef struct _CLASSIFICATION_RULE { + UCHAR ucIPSrcAddrLen; + UCHAR ucIPSrcAddr[32]; + UCHAR ucIPDestAddrLen; + UCHAR ucIPDestAddr[32]; + UCHAR ucSrcPortRangeLen; + UCHAR ucSrcPortRange[4]; + UCHAR ucDestPortRangeLen; + UCHAR ucDestPortRange[4]; + USHORT usVcid; +} CLASSIFICATION_RULE, *PCLASSIFICATION_RULE; + +typedef struct _CLASSIFICATION_ONLY { + USHORT usVcid; + ULONG DestIpAddress; + ULONG DestIpMask; + USHORT usPortLo; + USHORT usPortHi; + BOOLEAN bIpVersion; + UCHAR ucDestinationAddress[16]; } CLASSIFICATION_ONLY, *PCLASSIFICATION_ONLY; - #define MAX_IP_RANGE_LENGTH 4 #define MAX_PORT_RANGE 4 #define MAX_PROTOCOL_LENGTH 32 #define IPV6_ADDRESS_SIZEINBYTES 0x10 -typedef union _U_IP_ADDRESS -{ - struct - { - ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH];//Source Ip Address Range - ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH];//Source Ip Mask Address Range +typedef union _U_IP_ADDRESS { + struct { + ULONG ulIpv4Addr[MAX_IP_RANGE_LENGTH]; /* Source Ip Address Range */ + ULONG ulIpv4Mask[MAX_IP_RANGE_LENGTH]; /* Source Ip Mask Address Range */ }; - struct - { - ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4];//Source Ip Address Range - ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4];//Source Ip Mask Address Range - + struct { + ULONG ulIpv6Addr[MAX_IP_RANGE_LENGTH * 4]; /* Source Ip Address Range */ + ULONG ulIpv6Mask[MAX_IP_RANGE_LENGTH * 4]; /* Source Ip Mask Address Range */ }; - struct - { - UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; - UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; + struct { + UCHAR ucIpv4Address[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; + UCHAR ucIpv4Mask[MAX_IP_RANGE_LENGTH * IP_LENGTH_OF_ADDRESS]; }; - struct - { - UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; - UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; + struct { + UCHAR ucIpv6Address[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; + UCHAR ucIpv6Mask[MAX_IP_RANGE_LENGTH * IPV6_ADDRESS_SIZEINBYTES]; }; -}U_IP_ADDRESS; +} U_IP_ADDRESS; struct _packet_info; -typedef struct _S_HDR_SUPRESSION_CONTEXTINFO -{ +typedef struct _S_HDR_SUPRESSION_CONTEXTINFO { + UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; /* Intermediate buffer to accumulate pkt Header for PHS */ + UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; /* Intermediate buffer containing pkt Header after PHS */ +} S_HDR_SUPRESSION_CONTEXTINFO; + +typedef struct _S_CLASSIFIER_RULE { + ULONG ulSFID; + UCHAR ucReserved[2]; + B_UINT16 uiClassifierRuleIndex; + BOOLEAN bUsed; + USHORT usVCID_Value; + B_UINT8 u8ClassifierRulePriority; /* This field detemines the Classifier Priority */ + U_IP_ADDRESS stSrcIpAddress; + UCHAR ucIPSourceAddressLength; /* Ip Source Address Length */ - UCHAR ucaHdrSupressionInBuf[MAX_PHS_LENGTHS]; //Intermediate buffer to accumulate pkt Header for PHS - UCHAR ucaHdrSupressionOutBuf[MAX_PHS_LENGTHS + PHSI_LEN]; //Intermediate buffer containing pkt Header after PHS + U_IP_ADDRESS stDestIpAddress; + UCHAR ucIPDestinationAddressLength; /* Ip Destination Address Length */ + UCHAR ucIPTypeOfServiceLength; /* Type of service Length */ + UCHAR ucTosLow; /* Tos Low */ + UCHAR ucTosHigh; /* Tos High */ + UCHAR ucTosMask; /* Tos Mask */ -}S_HDR_SUPRESSION_CONTEXTINFO; + UCHAR ucProtocolLength; /* protocol Length */ + UCHAR ucProtocol[MAX_PROTOCOL_LENGTH]; /* protocol Length */ + USHORT usSrcPortRangeLo[MAX_PORT_RANGE]; + USHORT usSrcPortRangeHi[MAX_PORT_RANGE]; + UCHAR ucSrcPortRangeLength; + USHORT usDestPortRangeLo[MAX_PORT_RANGE]; + USHORT usDestPortRangeHi[MAX_PORT_RANGE]; + UCHAR ucDestPortRangeLength; -typedef struct _S_CLASSIFIER_RULE -{ - ULONG ulSFID; - UCHAR ucReserved[2]; - B_UINT16 uiClassifierRuleIndex; - BOOLEAN bUsed; - USHORT usVCID_Value; - B_UINT8 u8ClassifierRulePriority; //This field detemines the Classifier Priority - U_IP_ADDRESS stSrcIpAddress; - UCHAR ucIPSourceAddressLength;//Ip Source Address Length - - U_IP_ADDRESS stDestIpAddress; - UCHAR ucIPDestinationAddressLength;//Ip Destination Address Length - UCHAR ucIPTypeOfServiceLength;//Type of service Length - UCHAR ucTosLow;//Tos Low - UCHAR ucTosHigh;//Tos High - UCHAR ucTosMask;//Tos Mask - - UCHAR ucProtocolLength;//protocol Length - UCHAR ucProtocol[MAX_PROTOCOL_LENGTH];//protocol Length - USHORT usSrcPortRangeLo[MAX_PORT_RANGE]; - USHORT usSrcPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucSrcPortRangeLength; - - USHORT usDestPortRangeLo[MAX_PORT_RANGE]; - USHORT usDestPortRangeHi[MAX_PORT_RANGE]; - UCHAR ucDestPortRangeLength; - - BOOLEAN bProtocolValid; - BOOLEAN bTOSValid; - BOOLEAN bDestIpValid; - BOOLEAN bSrcIpValid; - - //For IPv6 Addressing - UCHAR ucDirection; - BOOLEAN bIpv6Protocol; - UINT32 u32PHSRuleID; - S_PHS_RULE sPhsRule; - UCHAR u8AssociatedPHSI; - - //Classification fields for ETH CS + BOOLEAN bProtocolValid; + BOOLEAN bTOSValid; + BOOLEAN bDestIpValid; + BOOLEAN bSrcIpValid; + + /* For IPv6 Addressing */ + UCHAR ucDirection; + BOOLEAN bIpv6Protocol; + UINT32 u32PHSRuleID; + S_PHS_RULE sPhsRule; + UCHAR u8AssociatedPHSI; + + /* Classification fields for ETH CS */ UCHAR ucEthCSSrcMACLen; UCHAR au8EThCSSrcMAC[MAC_ADDRESS_SIZE]; UCHAR au8EThCSSrcMACMask[MAC_ADDRESS_SIZE]; @@ -180,71 +157,67 @@ typedef struct _S_CLASSIFIER_RULE UCHAR usUserPriority[2]; USHORT usVLANID; USHORT usValidityBitMap; -}S_CLASSIFIER_RULE; -//typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE; - -typedef struct _S_FRAGMENTED_PACKET_INFO -{ - BOOLEAN bUsed; - ULONG ulSrcIpAddress; - USHORT usIpIdentification; - S_CLASSIFIER_RULE *pstMatchedClassifierEntry; - BOOLEAN bOutOfOrderFragment; -}S_FRAGMENTED_PACKET_INFO,*PS_FRAGMENTED_PACKET_INFO; - -struct _packet_info -{ - //classification extension Rule - ULONG ulSFID; - USHORT usVCID_Value; - UINT uiThreshold; - // This field determines the priority of the SF Queues - B_UINT8 u8TrafficPriority; - - BOOLEAN bValid; - BOOLEAN bActive; - BOOLEAN bActivateRequestSent; - - B_UINT8 u8QueueType;//BE or rtPS - - UINT uiMaxBucketSize;//maximum size of the bucket for the queue - UINT uiCurrentQueueDepthOnTarget; - UINT uiCurrentBytesOnHost; - UINT uiCurrentPacketsOnHost; - UINT uiDroppedCountBytes; - UINT uiDroppedCountPackets; - UINT uiSentBytes; - UINT uiSentPackets; - UINT uiCurrentDrainRate; - UINT uiThisPeriodSentBytes; +} S_CLASSIFIER_RULE; +/* typedef struct _S_CLASSIFIER_RULE S_CLASSIFIER_RULE; */ + +typedef struct _S_FRAGMENTED_PACKET_INFO { + BOOLEAN bUsed; + ULONG ulSrcIpAddress; + USHORT usIpIdentification; + S_CLASSIFIER_RULE *pstMatchedClassifierEntry; + BOOLEAN bOutOfOrderFragment; +} S_FRAGMENTED_PACKET_INFO, *PS_FRAGMENTED_PACKET_INFO; + +struct _packet_info { + /* classification extension Rule */ + ULONG ulSFID; + USHORT usVCID_Value; + UINT uiThreshold; + /* This field determines the priority of the SF Queues */ + B_UINT8 u8TrafficPriority; + + BOOLEAN bValid; + BOOLEAN bActive; + BOOLEAN bActivateRequestSent; + + B_UINT8 u8QueueType; /* BE or rtPS */ + + UINT uiMaxBucketSize; /* maximum size of the bucket for the queue */ + UINT uiCurrentQueueDepthOnTarget; + UINT uiCurrentBytesOnHost; + UINT uiCurrentPacketsOnHost; + UINT uiDroppedCountBytes; + UINT uiDroppedCountPackets; + UINT uiSentBytes; + UINT uiSentPackets; + UINT uiCurrentDrainRate; + UINT uiThisPeriodSentBytes; LARGE_INTEGER liDrainCalculated; - UINT uiCurrentTokenCount; - LARGE_INTEGER liLastUpdateTokenAt; - UINT uiMaxAllowedRate; - UINT NumOfPacketsSent; - UCHAR ucDirection; - USHORT usCID; + UINT uiCurrentTokenCount; + LARGE_INTEGER liLastUpdateTokenAt; + UINT uiMaxAllowedRate; + UINT NumOfPacketsSent; + UCHAR ucDirection; + USHORT usCID; S_MIBS_EXTSERVICEFLOW_PARAMETERS stMibsExtServiceFlowTable; - UINT uiCurrentRxRate; - UINT uiThisPeriodRxBytes; - UINT uiTotalRxBytes; - UINT uiTotalTxBytes; - UINT uiPendedLast; - UCHAR ucIpVersion; - - union - { - struct - { - struct sk_buff* FirstTxQueue; - struct sk_buff* LastTxQueue; + UINT uiCurrentRxRate; + UINT uiThisPeriodRxBytes; + UINT uiTotalRxBytes; + UINT uiTotalTxBytes; + UINT uiPendedLast; + UCHAR ucIpVersion; + + union { + struct { + struct sk_buff *FirstTxQueue; + struct sk_buff *LastTxQueue; }; - struct - { - struct sk_buff* ControlHead; - struct sk_buff* ControlTail; + struct { + struct sk_buff *ControlHead; + struct sk_buff *ControlTail; }; }; + BOOLEAN bProtocolValid; BOOLEAN bTOSValid; BOOLEAN bDestIpValid; @@ -255,226 +228,209 @@ struct _packet_info BOOLEAN bAuthorizedSet; BOOLEAN bClassifierPriority; UCHAR ucServiceClassName[MAX_CLASS_NAME_LENGTH]; - BOOLEAN bHeaderSuppressionEnabled; + BOOLEAN bHeaderSuppressionEnabled; spinlock_t SFQueueLock; - void *pstSFIndication; + void *pstSFIndication; struct timeval stLastUpdateTokenAt; - atomic_t uiPerSFTxResourceCount; + atomic_t uiPerSFTxResourceCount; UINT uiMaxLatency; - UCHAR bIPCSSupport; - UCHAR bEthCSSupport; + UCHAR bIPCSSupport; + UCHAR bEthCSSupport; }; typedef struct _packet_info PacketInfo; - -typedef struct _PER_TARANG_DATA -{ - struct _PER_TARANG_DATA * next; - struct _MINI_ADAPTER * Adapter; - struct sk_buff* RxAppControlHead; - struct sk_buff* RxAppControlTail; - volatile INT AppCtrlQueueLen; - BOOLEAN MacTracingEnabled; - BOOLEAN bApplicationToExit; - S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs; - ULONG RxCntrlMsgBitMask; +typedef struct _PER_TARANG_DATA { + struct _PER_TARANG_DATA *next; + struct _MINI_ADAPTER *Adapter; + struct sk_buff *RxAppControlHead; + struct sk_buff *RxAppControlTail; + int AppCtrlQueueLen; + BOOLEAN MacTracingEnabled; + BOOLEAN bApplicationToExit; + S_MIBS_DROPPED_APP_CNTRL_MESSAGES stDroppedAppCntrlMsgs; + ULONG RxCntrlMsgBitMask; } PER_TARANG_DATA, *PPER_TARANG_DATA; - #ifdef REL_4_1 -typedef struct _TARGET_PARAMS -{ - B_UINT32 m_u32CfgVersion; - - // Scanning Related Params - B_UINT32 m_u32CenterFrequency; - B_UINT32 m_u32BandAScan; - B_UINT32 m_u32BandBScan; - B_UINT32 m_u32BandCScan; - - // QoS Params - B_UINT32 m_u32minGrantsize; // size of minimum grant is 0 or 6 - B_UINT32 m_u32PHSEnable; - - // HO Params - B_UINT32 m_u32HoEnable; - B_UINT32 m_u32HoReserved1; - B_UINT32 m_u32HoReserved2; - - // Power Control Params - B_UINT32 m_u32MimoEnable; - B_UINT32 m_u32SecurityEnable; +typedef struct _TARGET_PARAMS { + B_UINT32 m_u32CfgVersion; + + /* Scanning Related Params */ + B_UINT32 m_u32CenterFrequency; + B_UINT32 m_u32BandAScan; + B_UINT32 m_u32BandBScan; + B_UINT32 m_u32BandCScan; + + /* QoS Params */ + B_UINT32 m_u32minGrantsize; /* size of minimum grant is 0 or 6 */ + B_UINT32 m_u32PHSEnable; + + /* HO Params */ + B_UINT32 m_u32HoEnable; + B_UINT32 m_u32HoReserved1; + B_UINT32 m_u32HoReserved2; + + /* Power Control Params */ + B_UINT32 m_u32MimoEnable; + B_UINT32 m_u32SecurityEnable; /* - * bit 1: 1 Idlemode enable; - * bit 2: 1 Sleepmode Enable - */ - B_UINT32 m_u32PowerSavingModesEnable; - /* PowerSaving Mode Options: - bit 0 = 1: CPE mode - to keep pcmcia if alive; - bit 1 = 1: CINR reporing in Idlemode Msg - bit 2 = 1: Default PSC Enable in sleepmode*/ - B_UINT32 m_u32PowerSavingModeOptions; - - B_UINT32 m_u32ArqEnable; - - // From Version #3, the HARQ section renamed as general - B_UINT32 m_u32HarqEnable; - // EEPROM Param Location - B_UINT32 m_u32EEPROMFlag; - /* BINARY TYPE - 4th MSByte: - * Interface Type - 3rd MSByte: - * Vendor Type - 2nd MSByte - */ - // Unused - LSByte - B_UINT32 m_u32Customize; - B_UINT32 m_u32ConfigBW; /* In Hz */ - B_UINT32 m_u32ShutDownTimer; - - - B_UINT32 m_u32RadioParameter; - B_UINT32 m_u32PhyParameter1; - B_UINT32 m_u32PhyParameter2; - B_UINT32 m_u32PhyParameter3; + * bit 1: 1 Idlemode enable; + * bit 2: 1 Sleepmode Enable + */ + B_UINT32 m_u32PowerSavingModesEnable; + /* PowerSaving Mode Options: + * bit 0 = 1: CPE mode - to keep pcmcia if alive; + * bit 1 = 1: CINR reporing in Idlemode Msg + * bit 2 = 1: Default PSC Enable in sleepmode + */ + B_UINT32 m_u32PowerSavingModeOptions; + + B_UINT32 m_u32ArqEnable; + + /* From Version #3, the HARQ section renamed as general */ + B_UINT32 m_u32HarqEnable; + /* EEPROM Param Location */ + B_UINT32 m_u32EEPROMFlag; + /* BINARY TYPE - 4th MSByte: + * Interface Type - 3rd MSByte: + * Vendor Type - 2nd MSByte + */ + /* Unused - LSByte */ + B_UINT32 m_u32Customize; + B_UINT32 m_u32ConfigBW; /* In Hz */ + B_UINT32 m_u32ShutDownTimer; + B_UINT32 m_u32RadioParameter; + B_UINT32 m_u32PhyParameter1; + B_UINT32 m_u32PhyParameter2; + B_UINT32 m_u32PhyParameter3; /* in eval mode only; - * lower 16bits = basic cid for testing; - * then bit 16 is test cqich, - * bit 17 test init rang; - * bit 18 test periodic rang - * bit 19 is test harq ack/nack - */ - B_UINT32 m_u32TestOptions; - + * lower 16bits = basic cid for testing; + * then bit 16 is test cqich, + * bit 17 test init rang; + * bit 18 test periodic rang + * bit 19 is test harq ack/nack + */ + B_UINT32 m_u32TestOptions; B_UINT32 m_u32MaxMACDataperDLFrame; B_UINT32 m_u32MaxMACDataperULFrame; - B_UINT32 m_u32Corr2MacFlags; - //adding driver params. - B_UINT32 HostDrvrConfig1; - B_UINT32 HostDrvrConfig2; - B_UINT32 HostDrvrConfig3; - B_UINT32 HostDrvrConfig4; - B_UINT32 HostDrvrConfig5; - B_UINT32 HostDrvrConfig6; - B_UINT32 m_u32SegmentedPUSCenable; - - // BAMC enable - but 4.x does not support this feature - // This is added just to sync 4.x and 5.x CFGs + /* adding driver params. */ + B_UINT32 HostDrvrConfig1; + B_UINT32 HostDrvrConfig2; + B_UINT32 HostDrvrConfig3; + B_UINT32 HostDrvrConfig4; + B_UINT32 HostDrvrConfig5; + B_UINT32 HostDrvrConfig6; + B_UINT32 m_u32SegmentedPUSCenable; + + /* BAMC enable - but 4.x does not support this feature + * This is added just to sync 4.x and 5.x CFGs + */ B_UINT32 m_u32BandAMCEnable; } STARGETPARAMS, *PSTARGETPARAMS; #endif -typedef struct _STTARGETDSXBUFFER -{ - ULONG ulTargetDsxBuffer; - B_UINT16 tid; - BOOLEAN valid; -}STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER; +typedef struct _STTARGETDSXBUFFER { + ULONG ulTargetDsxBuffer; + B_UINT16 tid; + BOOLEAN valid; +} STTARGETDSXBUFFER, *PSTTARGETDSXBUFFER; -typedef INT (*FP_FLASH_WRITE)(struct _MINI_ADAPTER*,UINT,PVOID); +typedef int (*FP_FLASH_WRITE)(struct _MINI_ADAPTER *, UINT, PVOID); -typedef INT (*FP_FLASH_WRITE_STATUS)(struct _MINI_ADAPTER*,UINT,PVOID); +typedef int (*FP_FLASH_WRITE_STATUS)(struct _MINI_ADAPTER *, UINT, PVOID); -/** -Driver adapter data structure -*/ -struct _MINI_ADAPTER -{ - struct _MINI_ADAPTER *next; +/* + * Driver adapter data structure + */ +struct _MINI_ADAPTER { + struct _MINI_ADAPTER *next; struct net_device *dev; u32 msg_enable; - - CHAR *caDsxReqResp; + CHAR *caDsxReqResp; atomic_t ApplicationRunning; - volatile INT CtrlQueueLen; - atomic_t AppCtrlQueueLen; - BOOLEAN AppCtrlQueueOverFlow; + BOOLEAN AppCtrlQueueOverFlow; atomic_t CurrentApplicationCount; - atomic_t RegisteredApplicationCount; - BOOLEAN LinkUpStatus; - BOOLEAN TimerActive; + atomic_t RegisteredApplicationCount; + BOOLEAN LinkUpStatus; + BOOLEAN TimerActive; u32 StatisticsPointer; struct sk_buff *RxControlHead; struct sk_buff *RxControlTail; - struct semaphore RxAppControlQueuelock; struct semaphore fw_download_sema; - - PPER_TARANG_DATA pTarangs; - spinlock_t control_queue_lock; + PPER_TARANG_DATA pTarangs; + spinlock_t control_queue_lock; wait_queue_head_t process_read_wait_queue; - // the pointer to the first packet we have queued in send - // deserialized miniport support variables - atomic_t TotalPacketCount; - atomic_t TxPktAvail; - - // this to keep track of the Tx and Rx MailBox Registers. - atomic_t CurrNumFreeTxDesc; - // to keep track the no of byte received - USHORT PrevNumRecvDescs; - USHORT CurrNumRecvDescs; - UINT u32TotalDSD; - PacketInfo PackInfo[NO_OF_QUEUES]; + /* the pointer to the first packet we have queued in send + * deserialized miniport support variables + */ + atomic_t TotalPacketCount; + atomic_t TxPktAvail; + + /* this to keep track of the Tx and Rx MailBox Registers. */ + atomic_t CurrNumFreeTxDesc; + /* to keep track the no of byte received */ + USHORT PrevNumRecvDescs; + USHORT CurrNumRecvDescs; + UINT u32TotalDSD; + PacketInfo PackInfo[NO_OF_QUEUES]; S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; - BOOLEAN TransferMode; + BOOLEAN TransferMode; /*************** qos ******************/ - BOOLEAN bETHCSEnabled; - - ULONG BEBucketSize; - ULONG rtPSBucketSize; - UCHAR LinkStatus; - BOOLEAN AutoLinkUp; - BOOLEAN AutoSyncup; - - int major; - int minor; - wait_queue_head_t tx_packet_wait_queue; - wait_queue_head_t process_rx_cntrlpkt; - atomic_t process_waiting; - BOOLEAN fw_download_done; - - char *txctlpacket[MAX_CNTRL_PKTS]; - atomic_t cntrlpktCnt ; - atomic_t index_app_read_cntrlpkt; - atomic_t index_wr_txcntrlpkt; - atomic_t index_rd_txcntrlpkt; - UINT index_datpkt; - struct semaphore rdmwrmsync; + BOOLEAN bETHCSEnabled; + ULONG BEBucketSize; + ULONG rtPSBucketSize; + UCHAR LinkStatus; + BOOLEAN AutoLinkUp; + BOOLEAN AutoSyncup; + + int major; + int minor; + wait_queue_head_t tx_packet_wait_queue; + wait_queue_head_t process_rx_cntrlpkt; + atomic_t process_waiting; + BOOLEAN fw_download_done; + + char *txctlpacket[MAX_CNTRL_PKTS]; + atomic_t cntrlpktCnt ; + atomic_t index_app_read_cntrlpkt; + atomic_t index_wr_txcntrlpkt; + atomic_t index_rd_txcntrlpkt; + UINT index_datpkt; + struct semaphore rdmwrmsync; STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; ULONG ulFreeTargetBufferCnt; - ULONG ulCurrentTargetBuffer; - ULONG ulTotalTargetBuffersAvailable; - - unsigned long chip_id; - - wait_queue_head_t lowpower_mode_wait_queue; - + ULONG ulCurrentTargetBuffer; + ULONG ulTotalTargetBuffersAvailable; + unsigned long chip_id; + wait_queue_head_t lowpower_mode_wait_queue; BOOLEAN bFlashBoot; BOOLEAN bBinDownloaded; BOOLEAN bCfgDownloaded; BOOLEAN bSyncUpRequestSent; USHORT usBestEffortQueueIndex; - - wait_queue_head_t ioctl_fw_dnld_wait_queue; - BOOLEAN waiting_to_fw_download_done; - pid_t fw_download_process_pid; + wait_queue_head_t ioctl_fw_dnld_wait_queue; + BOOLEAN waiting_to_fw_download_done; + pid_t fw_download_process_pid; PSTARGETPARAMS pstargetparams; - BOOLEAN device_removed; - BOOLEAN DeviceAccess; - BOOLEAN bIsAutoCorrectEnabled; - BOOLEAN bDDRInitDone; - INT DDRSetting; - ULONG ulPowerSaveMode; - spinlock_t txtransmitlock; - B_UINT8 txtransmit_running; + BOOLEAN device_removed; + BOOLEAN DeviceAccess; + BOOLEAN bIsAutoCorrectEnabled; + BOOLEAN bDDRInitDone; + int DDRSetting; + ULONG ulPowerSaveMode; + spinlock_t txtransmitlock; + B_UINT8 txtransmit_running; /* Thread for control packet handling */ - struct task_struct *control_packet_handler; + struct task_struct *control_packet_handler; /* thread for transmitting packets. */ - struct task_struct *transmit_packet_thread; + struct task_struct *transmit_packet_thread; /* LED Related Structures */ LED_INFO_STRUCT LEDInfo; @@ -482,39 +438,38 @@ struct _MINI_ADAPTER /* Driver State for LED Blinking */ LedEventInfo_t DriverState; /* Interface Specific */ - PVOID pvInterfaceAdapter; - int (*bcm_file_download)( PVOID, - struct file *, - unsigned int); - int (*bcm_file_readback_from_chip)( PVOID, - struct file *, - unsigned int); - INT (*interface_rdm)(PVOID, - UINT , - PVOID , - INT); - INT (*interface_wrm)(PVOID, - UINT , - PVOID , - INT); + PVOID pvInterfaceAdapter; + int (*bcm_file_download)(PVOID, + struct file *, + unsigned int); + int (*bcm_file_readback_from_chip)(PVOID, + struct file *, + unsigned int); + int (*interface_rdm)(PVOID, + UINT, + PVOID, + int); + int (*interface_wrm)(PVOID, + UINT, + PVOID, + int); int (*interface_transmit)(PVOID, PVOID , UINT); BOOLEAN IdleMode; BOOLEAN bDregRequestSentInIdleMode; BOOLEAN bTriedToWakeUpFromlowPowerMode; BOOLEAN bShutStatus; BOOLEAN bWakeUpDevice; - unsigned int usIdleModePattern; - //BOOLEAN bTriedToWakeUpFromShutdown; + unsigned int usIdleModePattern; + /* BOOLEAN bTriedToWakeUpFromShutdown; */ BOOLEAN bLinkDownRequested; - - int downloadDDR; - PHS_DEVICE_EXTENSION stBCMPhsContext; - S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; + int downloadDDR; + PHS_DEVICE_EXTENSION stBCMPhsContext; + S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; uint8_t ucaPHSPktRestoreBuf[2048]; uint8_t bPHSEnabled; BOOLEAN AutoFirmDld; - BOOLEAN bMipsConfig; - BOOLEAN bDPLLConfig; + BOOLEAN bMipsConfig; + BOOLEAN bDPLLConfig; UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; UINT32 aRxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; S_FRAGMENTED_PACKET_INFO astFragmentedPktClassifierTable[MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES]; @@ -527,108 +482,101 @@ struct _MINI_ADAPTER BOOLEAN bStatusWrite; UINT uiNVMDSDSize; UINT uiVendorExtnFlag; - //it will always represent chosen DSD at any point of time. - // Generally it is Active DSD but in case of NVM RD/WR it might be different. + /* it will always represent chosen DSD at any point of time. + * Generally it is Active DSD but in case of NVM RD/WR it might be different. + */ UINT ulFlashCalStart; - ULONG ulFlashControlSectionStart; - ULONG ulFlashWriteSize; - ULONG ulFlashID; - FP_FLASH_WRITE fpFlashWrite; - FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck; - + ULONG ulFlashControlSectionStart; + ULONG ulFlashWriteSize; + ULONG ulFlashID; + FP_FLASH_WRITE fpFlashWrite; + FP_FLASH_WRITE_STATUS fpFlashWriteWithStatusCheck; struct semaphore NVMRdmWrmLock; + struct device *pstCreatedClassDevice; - struct device *pstCreatedClassDevice; - -// BOOLEAN InterfaceUpStatus; - PFLASH2X_CS_INFO psFlash2xCSInfo; - PFLASH_CS_INFO psFlashCSInfo ; + /* BOOLEAN InterfaceUpStatus; */ + PFLASH2X_CS_INFO psFlash2xCSInfo; + PFLASH_CS_INFO psFlashCSInfo; PFLASH2X_VENDORSPECIFIC_INFO psFlash2xVendorInfo; - UINT uiFlashBaseAdd; //Flash start address - UINT uiActiveISOOffset; //Active ISO offset chosen before f/w download - FLASH2X_SECTION_VAL eActiveISO; //Active ISO section val - FLASH2X_SECTION_VAL eActiveDSD; //Active DSD val chosen before f/w download - UINT uiActiveDSDOffsetAtFwDld; //For accessing Active DSD chosen before f/w download - UINT uiFlashLayoutMajorVersion ; - UINT uiFlashLayoutMinorVersion; - BOOLEAN bAllDSDWriteAllow ; - BOOLEAN bSigCorrupted ; - //this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately. - BOOLEAN bHeaderChangeAllowed ; - INT SelectedChip ; - BOOLEAN bEndPointHalted; - //while bFlashRawRead will be true, Driver ignore map lay out and consider flash as of without any map. - BOOLEAN bFlashRawRead; - BOOLEAN bPreparingForLowPowerMode ; - BOOLEAN bDoSuspend ; - UINT syscfgBefFwDld ; - BOOLEAN StopAllXaction ; - UINT32 liTimeSinceLastNetEntry; //Used to Support extended CAPI requirements from + UINT uiFlashBaseAdd; /* Flash start address */ + UINT uiActiveISOOffset; /* Active ISO offset chosen before f/w download */ + FLASH2X_SECTION_VAL eActiveISO; /* Active ISO section val */ + FLASH2X_SECTION_VAL eActiveDSD; /* Active DSD val chosen before f/w download */ + UINT uiActiveDSDOffsetAtFwDld; /* For accessing Active DSD chosen before f/w download */ + UINT uiFlashLayoutMajorVersion; + UINT uiFlashLayoutMinorVersion; + BOOLEAN bAllDSDWriteAllow; + BOOLEAN bSigCorrupted; + /* this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately. */ + BOOLEAN bHeaderChangeAllowed; + int SelectedChip; + BOOLEAN bEndPointHalted; + /* while bFlashRawRead will be true, Driver ignore map lay out and consider flash as of without any map. */ + BOOLEAN bFlashRawRead; + BOOLEAN bPreparingForLowPowerMode; + BOOLEAN bDoSuspend; + UINT syscfgBefFwDld; + BOOLEAN StopAllXaction; + UINT32 liTimeSinceLastNetEntry; /* Used to Support extended CAPI requirements from */ struct semaphore LowPowerModeSync; - ULONG liDrainCalculated; - UINT gpioBitMap; - - S_BCM_DEBUG_STATE stDebugState; - + ULONG liDrainCalculated; + UINT gpioBitMap; + S_BCM_DEBUG_STATE stDebugState; }; typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; -#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) +#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) struct _ETH_HEADER_STRUC { - UCHAR au8DestinationAddress[6]; - UCHAR au8SourceAddress[6]; - USHORT u16Etype; -}__attribute__((packed)); + UCHAR au8DestinationAddress[6]; + UCHAR au8SourceAddress[6]; + USHORT u16Etype; +} __packed; typedef struct _ETH_HEADER_STRUC ETH_HEADER_STRUC, *PETH_HEADER_STRUC; +typedef struct FirmwareInfo { + void __user *pvMappedFirmwareAddress; + ULONG u32FirmwareLength; + ULONG u32StartingAddress; +} __packed FIRMWARE_INFO, *PFIRMWARE_INFO; -typedef struct FirmwareInfo -{ - void __user * pvMappedFirmwareAddress; - ULONG u32FirmwareLength; - ULONG u32StartingAddress; -}__attribute__((packed)) FIRMWARE_INFO, *PFIRMWARE_INFO; - -// holds the value of net_device structure.. +/* holds the value of net_device structure.. */ extern struct net_device *gblpnetdev; -typedef struct _cntl_pkt{ - PMINI_ADAPTER Adapter; - PLEADER PLeader; -}cntl_pkt; +typedef struct _cntl_pkt { + PMINI_ADAPTER Adapter; + PLEADER PLeader; +} cntl_pkt; typedef LINK_REQUEST CONTROL_MESSAGE; -typedef struct _DDR_SETTING -{ +typedef struct _DDR_SETTING { UINT ulRegAddress; UINT ulRegValue; -}DDR_SETTING, *PDDR_SETTING; +} DDR_SETTING, *PDDR_SETTING; typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE; -INT -InitAdapter(PMINI_ADAPTER psAdapter); - -// ===================================================================== -// Beceem vendor request codes for EP0 -// ===================================================================== +int InitAdapter(PMINI_ADAPTER psAdapter); -#define BCM_REQUEST_READ 0x2 -#define BCM_REQUEST_WRITE 0x1 -#define EP2_MPS_REG 0x0F0110A0 -#define EP2_MPS 0x40 +/* ===================================================================== + * Beceem vendor request codes for EP0 + * ===================================================================== + */ -#define EP2_CFG_REG 0x0F0110A8 -#define EP2_CFG_INT 0x27 -#define EP2_CFG_BULK 0x25 +#define BCM_REQUEST_READ 0x2 +#define BCM_REQUEST_WRITE 0x1 +#define EP2_MPS_REG 0x0F0110A0 +#define EP2_MPS 0x40 -#define EP4_MPS_REG 0x0F0110F0 -#define EP4_MPS 0x8C +#define EP2_CFG_REG 0x0F0110A8 +#define EP2_CFG_INT 0x27 +#define EP2_CFG_BULK 0x25 -#define EP4_CFG_REG 0x0F0110F8 +#define EP4_MPS_REG 0x0F0110F0 +#define EP4_MPS 0x8C -#define ISO_MPS_REG 0x0F0110C8 -#define ISO_MPS 0x00000000 +#define EP4_CFG_REG 0x0F0110F8 +#define ISO_MPS_REG 0x0F0110C8 +#define ISO_MPS 0x00000000 #define EP1 0 #define EP2 1 @@ -637,12 +585,9 @@ InitAdapter(PMINI_ADAPTER psAdapter); #define EP5 4 #define EP6 5 - -typedef enum eInterface_setting -{ +typedef enum eInterface_setting { DEFAULT_SETTING_0 = 0, ALTERNATE_SETTING_1 = 1, -}INTERFACE_SETTING; - -#endif //__ADAPTER_H__ +} INTERFACE_SETTING; +#endif /* __ADAPTER_H__ */ diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 1c7db81..2b46f4d 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -1115,20 +1115,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = (sizeof(asT3LP_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = (sizeof(asT3LP_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = (sizeof(asT3LP_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; @@ -1146,20 +1146,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=(sizeof(asT3LPB_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount=ARRAY_SIZE(asT3LPB_DDRSetting80MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = (sizeof(asT3LPB_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = (sizeof(asT3LPB_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; @@ -1167,7 +1167,7 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) case DDR_160_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(DDR_SET_NODE); + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; @@ -1181,19 +1181,19 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3_DDRSetting80MHz; - RegCount = (sizeof(asT3_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3_DDRSetting100MHz; - RegCount = (sizeof(asT3_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: psDDRSetting = asT3_DDRSetting133MHz; - RegCount = (sizeof(asT3_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; break; @@ -1207,20 +1207,20 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) { case DDR_80_MHZ: psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = (sizeof(asT3B_DDRSetting80MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; case DDR_100_MHZ: psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = (sizeof(asT3B_DDRSetting100MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; break; case DDR_133_MHZ: bOverrideSelfRefresh = TRUE; psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = (sizeof(asT3B_DDRSetting133MHz)/sizeof(DDR_SET_NODE)); + RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; diff --git a/drivers/staging/bcm/IPv6Protocol.c b/drivers/staging/bcm/IPv6Protocol.c index 5b4fd37..1da2164 100644 --- a/drivers/staging/bcm/IPv6Protocol.c +++ b/drivers/staging/bcm/IPv6Protocol.c @@ -1,51 +1,52 @@ #include "headers.h" -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header); +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header); +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header); static VOID DumpIpv6Header(IPV6Header *pstIpv6Header); -static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader,BOOLEAN *bParseDone,USHORT *pusPayloadLength) +static UCHAR *GetNextIPV6ChainedHeader(UCHAR **ppucPayload, + UCHAR *pucNextHeader, BOOLEAN *bParseDone, USHORT *pusPayloadLength) { UCHAR *pucRetHeaderPtr = NULL; UCHAR *pucPayloadPtr = NULL; USHORT usNextHeaderOffset = 0 ; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if((NULL == ppucPayload) || (*pusPayloadLength == 0) || (*bParseDone)) - { + if ((ppucPayload == NULL) || (*pusPayloadLength == 0) || + (*bParseDone)) { *bParseDone = TRUE; return NULL; - } pucRetHeaderPtr = *ppucPayload; pucPayloadPtr = *ppucPayload; - if(!pucRetHeaderPtr || !pucPayloadPtr) - { + if (!pucRetHeaderPtr || !pucPayloadPtr) { *bParseDone = TRUE; return NULL; } - //Get the Nextt Header Type + /* Get the Nextt Header Type */ *bParseDone = FALSE; - - switch(*pucNextHeader) - { + switch (*pucNextHeader) { case IPV6HDR_TYPE_HOPBYHOP: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 HopByHop Header"); - usNextHeaderOffset+=sizeof(IPV6HopByHopOptionsHeader); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 HopByHop Header"); + usNextHeaderOffset += sizeof(IPV6HopByHopOptionsHeader); } break; case IPV6HDR_TYPE_ROUTING: { IPV6RoutingHeader *pstIpv6RoutingHeader; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Routing Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Routing Header"); pstIpv6RoutingHeader = (IPV6RoutingHeader *)pucPayloadPtr; usNextHeaderOffset += sizeof(IPV6RoutingHeader); usNextHeaderOffset += pstIpv6RoutingHeader->ucNumAddresses * IPV6_ADDRESS_SIZEINBYTES; @@ -54,8 +55,10 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader break; case IPV6HDR_TYPE_FRAGMENTATION: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Fragmentation Header"); - usNextHeaderOffset+= sizeof(IPV6FragmentHeader); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Fragmentation Header"); + usNextHeaderOffset += sizeof(IPV6FragmentHeader); } break; @@ -63,9 +66,11 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader { IPV6DestOptionsHeader *pstIpv6DestOptsHdr = (IPV6DestOptionsHeader *)pucPayloadPtr; int nTotalOptions = pstIpv6DestOptsHdr->ucHdrExtLen; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 DestOpts Header Header"); - usNextHeaderOffset+= sizeof(IPV6DestOptionsHeader); - usNextHeaderOffset+= nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 DestOpts Header Header"); + usNextHeaderOffset += sizeof(IPV6DestOptionsHeader); + usNextHeaderOffset += nTotalOptions * IPV6_DESTOPTS_HDR_OPTIONSIZE ; } break; @@ -73,36 +78,43 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader { IPV6AuthenticationHeader *pstIpv6AuthHdr = (IPV6AuthenticationHeader *)pucPayloadPtr; int nHdrLen = pstIpv6AuthHdr->ucLength; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Authentication Header"); - usNextHeaderOffset+= nHdrLen * 4; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Authentication Header"); + usNextHeaderOffset += nHdrLen * 4; } break; case IPV6HDR_TYPE_ENCRYPTEDSECURITYPAYLOAD: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Encrypted Security Payload Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nIPv6 Encrypted Security Payload Header"); *bParseDone = TRUE; } break; case IPV6_ICMP_HDR_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " ICMP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nICMP Header"); *bParseDone = TRUE; } break; case TCP_HEADER_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nTCP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nTCP Header"); *bParseDone = TRUE; } break; case UDP_HEADER_TYPE: { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nUDP Header"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nUDP Header"); *bParseDone = TRUE; } break; - default : + default: { *bParseDone = TRUE; @@ -112,53 +124,49 @@ static UCHAR * GetNextIPV6ChainedHeader(UCHAR **ppucPayload,UCHAR *pucNextHeader } - if(*bParseDone == FALSE) - { - if(*pusPayloadLength <= usNextHeaderOffset) - { + if (*bParseDone == FALSE) { + if (*pusPayloadLength <= usNextHeaderOffset) { *bParseDone = TRUE; - } - else - { + } else { *pucNextHeader = *pucPayloadPtr; - pucPayloadPtr+=usNextHeaderOffset; - (*pusPayloadLength)-=usNextHeaderOffset; + pucPayloadPtr += usNextHeaderOffset; + (*pusPayloadLength) -= usNextHeaderOffset; } } - - *ppucPayload = pucPayloadPtr; return pucRetHeaderPtr; } -static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *pusDestPort,USHORT usPayloadLength,UCHAR ucNextHeader) +static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload, USHORT *pusSrcPort, + USHORT *pusDestPort, USHORT usPayloadLength, UCHAR ucNextHeader) { UCHAR *pIpv6HdrScanContext = pucPayload; BOOLEAN bDone = FALSE; - UCHAR ucHeaderType =0; + UCHAR ucHeaderType = 0; UCHAR *pucNextHeader = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - if( !pucPayload || (usPayloadLength == 0)) - { + if (!pucPayload || (usPayloadLength == 0)) return 0; - } *pusSrcPort = *pusDestPort = 0; ucHeaderType = ucNextHeader; - while(!bDone) - { - pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext,&ucHeaderType,&bDone,&usPayloadLength); - if(bDone) - { - if((ucHeaderType==TCP_HEADER_TYPE) || (ucHeaderType == UDP_HEADER_TYPE)) - { - *pusSrcPort=*((PUSHORT)(pucNextHeader)); - *pusDestPort=*((PUSHORT)(pucNextHeader+2)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, " \nProtocol Ports - Src Port :0x%x Dest Port : 0x%x",ntohs(*pusSrcPort),ntohs(*pusDestPort)); + while (!bDone) { + pucNextHeader = GetNextIPV6ChainedHeader(&pIpv6HdrScanContext, + &ucHeaderType, &bDone, &usPayloadLength); + if (bDone) { + if ((ucHeaderType == TCP_HEADER_TYPE) || + (ucHeaderType == UDP_HEADER_TYPE)) { + *pusSrcPort = *((PUSHORT)(pucNextHeader)); + *pusDestPort = *((PUSHORT)(pucNextHeader+2)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "\nProtocol Ports - Src Port :0x%x Dest Port : 0x%x", + ntohs(*pusSrcPort), + ntohs(*pusDestPort)); } break; @@ -168,92 +176,111 @@ static UCHAR GetIpv6ProtocolPorts(UCHAR *pucPayload,USHORT *pusSrcPort,USHORT *p } - -USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control structure */ - PVOID pcIpHeader, /**<Pointer to the IP Hdr of the packet*/ - S_CLASSIFIER_RULE *pstClassifierRule ) +/* + * Arg 1 PMINI_ADAPTER Adapter is a pointer ot the driver contorl structure + * Arg 2 PVOID pcIpHeader is a pointer to the IP header of the packet + */ +USHORT IpVersion6(PMINI_ADAPTER Adapter, PVOID pcIpHeader, + S_CLASSIFIER_RULE *pstClassifierRule) { USHORT ushDestPort = 0; USHORT ushSrcPort = 0; - UCHAR ucNextProtocolAboveIP =0; + UCHAR ucNextProtocolAboveIP = 0; IPV6Header *pstIpv6Header = NULL; BOOLEAN bClassificationSucceed = FALSE; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "IpVersion6 ==========>\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "IpVersion6 ==========>\n"); pstIpv6Header = (IPV6Header *)pcIpHeader; DumpIpv6Header(pstIpv6Header); - //Try to get the next higher layer protocol and the Ports Nos if TCP or UDP + /* + * Try to get the next higher layer protocol + * and the Ports Nos if TCP or UDP + */ ucNextProtocolAboveIP = GetIpv6ProtocolPorts((UCHAR *)(pcIpHeader + sizeof(IPV6Header)), &ushSrcPort, &ushDestPort, pstIpv6Header->usPayloadLength, pstIpv6Header->ucNextHeader); - do - { - if(0 == pstClassifierRule->ucDirection) - { - //cannot be processed for classification. - // it is a down link connection + do { + if (pstClassifierRule->ucDirection == 0) { + /* + * cannot be processed for classification. + * it is a down link connection + */ break; } - if(!pstClassifierRule->bIpv6Protocol) - { - //We are looking for Ipv6 Classifiers . Lets ignore this classifier and try the next one. + if (!pstClassifierRule->bIpv6Protocol) { + /* + * We are looking for Ipv6 Classifiers + * Lets ignore this classifier and try the next one + */ break; } - bClassificationSucceed=MatchSrcIpv6Address(pstClassifierRule,pstIpv6Header); - if(!bClassificationSucceed) - break; + bClassificationSucceed = MatchSrcIpv6Address(pstClassifierRule, + pstIpv6Header); + if (!bClassificationSucceed) + break; - bClassificationSucceed=MatchDestIpv6Address(pstClassifierRule,pstIpv6Header); - if(!bClassificationSucceed) - break; + bClassificationSucceed = MatchDestIpv6Address(pstClassifierRule, + pstIpv6Header); + if (!bClassificationSucceed) + break; - //Match the protocol type.For IPv6 the next protocol at end of Chain of IPv6 prot headers - bClassificationSucceed=MatchProtocol(pstClassifierRule,ucNextProtocolAboveIP); - if(!bClassificationSucceed) - break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + /* + * Match the protocol type. + * For IPv6 the next protocol at end of + * Chain of IPv6 prot headers + */ + bClassificationSucceed = MatchProtocol(pstClassifierRule, + ucNextProtocolAboveIP); + if (!bClassificationSucceed) + break; - if((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) - { - //Match Src Port - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Source Port:%x\n",ntohs(ushSrcPort)); - bClassificationSucceed=MatchSrcPort(pstClassifierRule,ntohs(ushSrcPort)); - if(!bClassificationSucceed) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Protocol Matched"); + + if ((ucNextProtocolAboveIP == TCP_HEADER_TYPE) || + (ucNextProtocolAboveIP == UDP_HEADER_TYPE)) { + /* Match Src Port */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Source Port:%x\n", + ntohs(ushSrcPort)); + bClassificationSucceed = MatchSrcPort(pstClassifierRule, + ntohs(ushSrcPort)); + if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Src Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Src Port Matched"); - //Match Dest Port - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n",ntohs(ushDestPort)); - bClassificationSucceed=MatchDestPort(pstClassifierRule,ntohs(ushDestPort)); - if(!bClassificationSucceed) + /* Match Dest Port */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Destination Port:%x\n", + ntohs(ushDestPort)); + bClassificationSucceed = MatchDestPort(pstClassifierRule, + ntohs(ushDestPort)); + if (!bClassificationSucceed) break; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, "\nIPv6 Dest Port Matched"); } - }while(0); + } while (0); - if(TRUE==bClassificationSucceed) - { + if (bClassificationSucceed == TRUE) { INT iMatchedSFQueueIndex = 0; - iMatchedSFQueueIndex = SearchSfid(Adapter,pstClassifierRule->ulSFID); - if(iMatchedSFQueueIndex >= NO_OF_QUEUES) - { + iMatchedSFQueueIndex = SearchSfid(Adapter, pstClassifierRule->ulSFID); + if (iMatchedSFQueueIndex >= NO_OF_QUEUES) { bClassificationSucceed = FALSE; - } - else - { - if(FALSE == Adapter->PackInfo[iMatchedSFQueueIndex].bActive) - { + } else { + if (Adapter->PackInfo[iMatchedSFQueueIndex].bActive == FALSE) bClassificationSucceed = FALSE; - } } } @@ -261,52 +288,55 @@ USHORT IpVersion6(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru } -static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header) { - UINT uiLoopIndex=0; - UINT uiIpv6AddIndex=0; - UINT uiIpv6AddrNoLongWords = 4; + UINT uiLoopIndex = 0; + UINT uiIpv6AddIndex = 0; + UINT uiIpv6AddrNoLongWords = 4; ULONG aulSrcIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* - //This is the no. of Src Addresses ie Range of IP Addresses contained - //in the classifier rule for which we need to match - */ + * This is the no. of Src Addresses ie Range of IP Addresses contained + * in the classifier rule for which we need to match + */ UINT uiCountIPSrcAddresses = (UINT)pstClassifierRule->ucIPSourceAddressLength; - if(0 == uiCountIPSrcAddresses) + if (uiCountIPSrcAddresses == 0) return TRUE; - //First Convert the Ip Address in the packet to Host Endian order - for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) - { - aulSrcIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); - } + /* First Convert the Ip Address in the packet to Host Endian order */ + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) + aulSrcIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulSrcIpAddress[uiIpv6AddIndex]); - for(uiLoopIndex=0;uiLoopIndex<uiCountIPSrcAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Received Packet : \n "); + for (uiLoopIndex = 0; uiLoopIndex < uiCountIPSrcAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulSrcIP); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Mask In Classifier Rule: \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Mask In Classifier Rule:\n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Src Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Src Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex]); - for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) - { - if((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) - != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) - { - //Match failed for current Ipv6 Address.Try next Ipv6 Address + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + if ((pstClassifierRule->stSrcIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulSrcIP[uiIpv6AddIndex]) + != pstClassifierRule->stSrcIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { + /* + * Match failed for current Ipv6 Address + * Try next Ipv6 Address + */ break; } - if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) - { - //Match Found - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Src Ip Address Matched\n"); + if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { + /* Match Found */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "Ipv6 Src Ip Address Matched\n"); return TRUE; } } @@ -314,52 +344,56 @@ static BOOLEAN MatchSrcIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Head return FALSE; } -static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Header *pstIpv6Header) +static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule, + IPV6Header *pstIpv6Header) { - UINT uiLoopIndex=0; - UINT uiIpv6AddIndex=0; - UINT uiIpv6AddrNoLongWords = 4; + UINT uiLoopIndex = 0; + UINT uiIpv6AddIndex = 0; + UINT uiIpv6AddrNoLongWords = 4; ULONG aulDestIP[4]; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); /* - //This is the no. of Destination Addresses ie Range of IP Addresses contained - //in the classifier rule for which we need to match - */ + * This is the no. of Destination Addresses + * ie Range of IP Addresses contained in the classifier rule + * for which we need to match + */ UINT uiCountIPDestinationAddresses = (UINT)pstClassifierRule->ucIPDestinationAddressLength; - if(0 == uiCountIPDestinationAddresses) + if (uiCountIPDestinationAddresses == 0) return TRUE; - //First Convert the Ip Address in the packet to Host Endian order - for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) - { - aulDestIP[uiIpv6AddIndex]=ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); - } + /* First Convert the Ip Address in the packet to Host Endian order */ + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) + aulDestIP[uiIpv6AddIndex] = ntohl(pstIpv6Header->ulDestIpAddress[uiIpv6AddIndex]); - for(uiLoopIndex=0;uiLoopIndex<uiCountIPDestinationAddresses;uiLoopIndex+=uiIpv6AddrNoLongWords) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Received Packet : \n "); + for (uiLoopIndex = 0; uiLoopIndex < uiCountIPDestinationAddresses; uiLoopIndex += uiIpv6AddrNoLongWords) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Address In Received Packet :\n "); DumpIpv6Address(aulDestIP); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Mask In Classifier Rule: \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Mask In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex]); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "\n Destination Ipv6 Address In Classifier Rule : \n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "\n Destination Ipv6 Address In Classifier Rule :\n"); DumpIpv6Address(&pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex]); - for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) - { - if((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) - != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) - { - //Match failed for current Ipv6 Address.Try next Ipv6 Address + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + if ((pstClassifierRule->stDestIpAddress.ulIpv6Mask[uiLoopIndex+uiIpv6AddIndex] & aulDestIP[uiIpv6AddIndex]) + != pstClassifierRule->stDestIpAddress.ulIpv6Addr[uiLoopIndex+uiIpv6AddIndex]) { + /* + * Match failed for current Ipv6 Address. + * Try next Ipv6 Address + */ break; } - if(uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) - { - //Match Found - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Ipv6 Destination Ip Address Matched\n"); + if (uiIpv6AddIndex == uiIpv6AddrNoLongWords-1) { + /* Match Found */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, + DBG_LVL_ALL, + "Ipv6 Destination Ip Address Matched\n"); return TRUE; } } @@ -371,11 +405,11 @@ static BOOLEAN MatchDestIpv6Address(S_CLASSIFIER_RULE *pstClassifierRule,IPV6Hea VOID DumpIpv6Address(ULONG *puIpv6Address) { UINT uiIpv6AddrNoLongWords = 4; - UINT uiIpv6AddIndex=0; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - for(uiIpv6AddIndex=0;uiIpv6AddIndex<uiIpv6AddrNoLongWords;uiIpv6AddIndex++) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, ":%lx",puIpv6Address[uiIpv6AddIndex]); + UINT uiIpv6AddIndex = 0; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + for (uiIpv6AddIndex = 0; uiIpv6AddIndex < uiIpv6AddrNoLongWords; uiIpv6AddIndex++) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + ":%lx", puIpv6Address[uiIpv6AddIndex]); } } @@ -383,22 +417,35 @@ VOID DumpIpv6Address(ULONG *puIpv6Address) static VOID DumpIpv6Header(IPV6Header *pstIpv6Header) { UCHAR ucVersion; - UCHAR ucPrio ; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header---"); + UCHAR ucPrio; + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "----Ipv6 Header---"); ucVersion = pstIpv6Header->ucVersionPrio & 0xf0; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Version : %x \n",ucVersion); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Version : %x\n", ucVersion); ucPrio = pstIpv6Header->ucVersionPrio & 0x0f; - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Priority : %x \n",ucPrio); - //BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Flow Label : %x \n",(pstIpv6Header->ucVersionPrio &0xf0); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Payload Length : %x \n",ntohs(pstIpv6Header->usPayloadLength)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Next Header : %x \n",pstIpv6Header->ucNextHeader); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Hop Limit : %x \n",pstIpv6Header->ucHopLimit); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Src Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Priority : %x\n", ucPrio); + /* + * BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + * "Flow Label : %x\n",(pstIpv6Header->ucVersionPrio &0xf0); + */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Payload Length : %x\n", + ntohs(pstIpv6Header->usPayloadLength)); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Next Header : %x\n", pstIpv6Header->ucNextHeader); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Hop Limit : %x\n", pstIpv6Header->ucHopLimit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Src Address :\n"); DumpIpv6Address(pstIpv6Header->ulSrcIpAddress); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "Dest Address :\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "Dest Address :\n"); DumpIpv6Address(pstIpv6Header->ulDestIpAddress); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, "----Ipv6 Header End---"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV6_DBG, DBG_LVL_ALL, + "----Ipv6 Header End---"); } diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index c7725e1..8223a69 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -835,7 +835,7 @@ int reset_card_proc(PMINI_ADAPTER ps_adapter) Bcm_kill_all_URBs(psIntfAdapter); /* Reset the UMA-B Device */ if (ps_adapter->chip_id >= T3LPB) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reseting UMA-B\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Resetting UMA-B\n"); retval = usb_reset_device(psIntfAdapter->udev); psIntfAdapter->psAdapter->StopAllXaction = FALSE; diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 12c691d..3bbe3fd 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1,6 +1,5 @@ config COMEDI tristate "Data acquisition support (comedi)" - default N depends on m depends on BROKEN || FRV || M32R || MN10300 || SUPERH || TILE || X86 ---help--- @@ -14,10 +13,29 @@ config COMEDI_DEBUG This is an option for use by developers; most people should say N here. This enables comedi core and driver debugging. +config COMEDI_DEFAULT_BUF_SIZE_KB + int "Comedi default initial asynchronous buffer size in KiB" + default "2048" + depends on COMEDI != n + ---help--- + This is the default asynchronous buffer size which is used for + commands running in the background in kernel space. This + defaults to 2048 KiB of memory so that a 16 channel card + running at 10 kHz has of 2-4 seconds of buffer. + +config COMEDI_DEFAULT_BUF_MAXSIZE_KB + int "Comedi default maximum asynchronous buffer size in KiB" + default "20480" + depends on COMEDI != n + ---help--- + This is the default maximum asynchronous buffer size which can + be requested by a userspace program without root privileges. + This is set to 20480 KiB so that a fast I/O card with 16 + channels running at 100 kHz has 2-4 seconds of buffer. + menuconfig COMEDI_MISC_DRIVERS tristate "Comedi misc drivers" depends on COMEDI - default N ---help--- Enable comedi misc drivers to be built @@ -35,7 +53,6 @@ config COMEDI_KCOMEDILIB config COMEDI_BOND tristate "Device bonding support" depends on COMEDI_KCOMEDILIB - default N ---help--- Enable support for a driver to 'bond' (merge) multiple subdevices from multiple devices together as one. @@ -46,7 +63,6 @@ config COMEDI_BOND config COMEDI_TEST tristate "Fake waveform generator support" select COMEDI_FC - default N ---help--- Enable support for the fake waveform generator. This driver is mainly for testing purposes, but can also be used to @@ -58,7 +74,6 @@ config COMEDI_TEST config COMEDI_PARPORT tristate "Parallel port support" - default N ---help--- Enable support for the standard parallel port. A cheap and easy way to get a few more digital I/O lines. Steal @@ -70,7 +85,6 @@ config COMEDI_PARPORT config COMEDI_SERIAL2002 tristate "Driver for serial connected hardware" - default N ---help--- Enable support for serial connected hardware @@ -79,7 +93,6 @@ config COMEDI_SERIAL2002 config COMEDI_SKEL tristate "Comedi skeleton driver" - default N ---help--- Build the Skeleton driver, an example for driver writers @@ -91,7 +104,6 @@ endif # COMEDI_MISC_DRIVERS menuconfig COMEDI_ISA_DRIVERS tristate "Comedi ISA and PC/104 drivers" depends on COMEDI && ISA - default N ---help--- Enable comedi ISA and PC/104 drivers to be built @@ -103,7 +115,6 @@ if COMEDI_ISA_DRIVERS && ISA config COMEDI_ACL7225B tristate "ADlink NuDAQ ACL-7225b and compatibles support" - default N ---help--- Enable support for ADlink NuDAQ ACL-7225b and compatibles, ADlink ACL-7225b (acl7225b), ICP P16R16DIO (p16r16dio) @@ -113,7 +124,6 @@ config COMEDI_ACL7225B config COMEDI_PCL711 tristate "Advantech PCL-711/711b and ADlink ACL-8112 ISA card support" - default N ---help--- Enable support for Advantech PCL-711 and 711b, ADlink ACL-8112 @@ -123,7 +133,6 @@ config COMEDI_PCL711 config COMEDI_PCL724 tristate "Advantech PCL-722/724/731 and ADlink ACL-7122/7124/PET-48DIO" select COMEDI_8255 - default N ---help--- Enable support for Advantech PCL-724, PCL-722, PCL-731 and ADlink ACL-7122, ACL-7124, PET-48DIO ISA cards @@ -133,7 +142,6 @@ config COMEDI_PCL724 config COMEDI_PCL725 tristate "Advantech PCL-725 and compatible ISA card support" - default N ---help--- Enable support for Advantech PCL-725 and compatible ISA cards. @@ -142,7 +150,6 @@ config COMEDI_PCL725 config COMEDI_PCL726 tristate "Advantech PCL-726 and compatible ISA card support" - default N ---help--- Enable support for Advantech PCL-726 and compatible ISA cards. @@ -151,7 +158,6 @@ config COMEDI_PCL726 config COMEDI_PCL730 tristate "Advantech PCL-730 and ADlink ACL-7130 ISA card support" - default N ---help--- Enable support for Advantech PCL-730, ICP ISO-730 and ADlink ACL-7130 ISA cards @@ -162,7 +168,6 @@ config COMEDI_PCL730 config COMEDI_PCL812 tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" depends on VIRT_TO_BUS - default N ---help--- Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA, @@ -174,7 +179,6 @@ config COMEDI_PCL812 config COMEDI_PCL816 tristate "Advantech PCL-814 and PCL-816 ISA card support" depends on VIRT_TO_BUS - default N ---help--- Enable support for Advantech PCL-814 and PCL-816 ISA cards @@ -184,7 +188,6 @@ config COMEDI_PCL816 config COMEDI_PCL818 tristate "Advantech PCL-718 and PCL-818 ISA card support" depends on VIRT_TO_BUS - default N ---help--- Enable support for Advantech PCL-818 ISA cards PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718 @@ -195,7 +198,6 @@ config COMEDI_PCL818 config COMEDI_PCM3724 tristate "Advantech PCM-3724 PC/104 card support" select COMEDI_8255 - default N ---help--- Enable support for Advantech PCM-3724 PC/104 cards. @@ -204,16 +206,43 @@ config COMEDI_PCM3724 config COMEDI_PCM3730 tristate "Advantech PCM-3730 and clone PC/104 board support" - default N ---help--- Enable support for Advantech PCM-3730 and clone PC/104 boards To compile this driver as a module, choose M here: the module will be called pcm3730. +config COMEDI_AMPLC_DIO200_ISA + tristate "Amplicon PC212E/PC214E/PC215E/PC218E/PC272E" + select COMEDI_AMPLC_DIO200 + depends on COMEDI_ISA_DRIVERS + ---help--- + Enable support for Amplicon PC212E, PC214E, PC215E, PC218E and + PC272E ISA DIO boards + + To compile this driver as a module, choose M here: the module will be + called amplc_dio200. + +config COMEDI_AMPLC_PC236_ISA + tristate "Amplicon PC36AT DIO board support" + select COMEDI_AMPLC_PC236 + ---help--- + Enable support for Amplicon PC36AT ISA DIO board. + + To compile this driver as a module, choose M here: the module will be + called amplc_pc236. + +config COMEDI_AMPLC_PC263_ISA + tristate "Amplicon PC263 relay board support" + select COMEDI_AMPLC_PC263 + ---help--- + Enable support for Amplicon PC263 ISA relay board. + + To compile this driver as a module, choose M here: the module will be + called amplc_pc263. + config COMEDI_RTI800 tristate "Analog Devices RTI-800/815 ISA card support" - default N ---help--- Enable support for Analog Devices RTI-800/815 ISA cards @@ -222,7 +251,6 @@ config COMEDI_RTI800 config COMEDI_RTI802 tristate "Analog Devices RTI-802 ISA card support" - default N ---help--- Enable support for Analog Devices RTI-802 ISA cards @@ -233,18 +261,29 @@ config COMEDI_DAS16M1 tristate "MeasurementComputing CIO-DAS16/M1DAS-16 ISA card support" select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for Measurement Computing CIO-DAS16/M1 ISA cards. To compile this driver as a module, choose M here: the module will be called das16m1. +config COMEDI_DAS08_ISA + tristate "DAS-08 compatible ISA and PC/104 card support" + select COMEDI_DAS08 + ---help--- + Enable support for Keithley Metrabyte/ComputerBoards DAS08 + and compatible ISA and PC/104 cards: + Keithley Metrabyte/ComputerBoards DAS08, DAS08-PGM, DAS08-PGH, + DAS08-PGL, DAS08-AOH, DAS08-AOL, DAS08-AOM, DAS08/JR-AO, + DAS08/JR-16-AO, PC104-DAS08, DAS08/JR/16. + + To compile this driver as a module, choose M here: the module will be + called das08. + config COMEDI_DAS16 tristate "DAS-16 compatible ISA and PC/104 card support" select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for Keithley Metrabyte/ComputerBoards DAS16 and compatible ISA and PC/104 cards: @@ -261,7 +300,6 @@ config COMEDI_DAS16 config COMEDI_DAS800 tristate "DAS800 and compatible ISA card support" select COMEDI_FC - default N ---help--- Enable support for Keithley Metrabyte DAS800 and compatible ISA cards Keithley Metrabyte DAS-800, DAS-801, DAS-802 @@ -275,7 +313,6 @@ config COMEDI_DAS1800 tristate "DAS1800 and compatible ISA card support" depends on VIRT_TO_BUS select COMEDI_FC - default N ---help--- Enable support for DAS1800 and compatible ISA cards Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO, @@ -289,7 +326,6 @@ config COMEDI_DAS1800 config COMEDI_DAS6402 tristate "DAS6402 and compatible ISA card support" - default N ---help--- Enable support for DAS6402 and compatible ISA cards Computerboards, Keithley Metrabyte DAS6402 and compatibles @@ -299,7 +335,6 @@ config COMEDI_DAS6402 config COMEDI_DT2801 tristate "Data Translation DT2801 ISA card support" - default N ---help--- Enable support for Data Translation DT2801 ISA cards @@ -308,7 +343,6 @@ config COMEDI_DT2801 config COMEDI_DT2811 tristate "Data Translation DT2811 ISA card support" - default N ---help--- Enable support for Data Translation DT2811 ISA cards @@ -317,7 +351,6 @@ config COMEDI_DT2811 config COMEDI_DT2814 tristate "Data Translation DT2814 ISA card support" - default N ---help--- Enable support for Data Translation DT2814 ISA cards @@ -326,7 +359,6 @@ config COMEDI_DT2814 config COMEDI_DT2815 tristate "Data Translation DT2815 ISA card support" - default N ---help--- Enable support for Data Translation DT2815 ISA cards @@ -335,7 +367,6 @@ config COMEDI_DT2815 config COMEDI_DT2817 tristate "Data Translation DT2817 ISA card support" - default N ---help--- Enable support for Data Translation DT2817 ISA cards @@ -346,7 +377,6 @@ config COMEDI_DT282X tristate "Data Translation DT2821 series and DT-EZ ISA card support" select COMEDI_FC depends on VIRT_TO_BUS - default N ---help--- Enable support for Data Translation DT2821 series including DT-EZ DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI, @@ -358,7 +388,6 @@ config COMEDI_DT282X config COMEDI_DMM32AT tristate "Diamond Systems MM-32-AT PC/104 board support" - default N ---help--- Enable support for Diamond Systems MM-32-AT PC/104 boards @@ -367,7 +396,6 @@ config COMEDI_DMM32AT config COMEDI_FL512 tristate "FL512 ISA card support" - default N ---help--- Enable support for FL512 ISA card @@ -377,7 +405,6 @@ config COMEDI_FL512 config COMEDI_AIO_AIO12_8 tristate "I/O Products PC/104 AIO12-8 Analog I/O Board support" select COMEDI_8255 - default N ---help--- Enable support for I/O Products PC/104 AIO12-8 Analog I/O Board @@ -386,7 +413,6 @@ config COMEDI_AIO_AIO12_8 config COMEDI_AIO_IIRO_16 tristate "I/O Products PC/104 IIRO16 Board support" - default N ---help--- Enable support for I/O Products PC/104 IIRO16 Relay And Isolated Input Board @@ -396,7 +422,6 @@ config COMEDI_AIO_IIRO_16 config COMEDI_C6XDIGIO tristate "Mechatronic Systems Inc. C6x_DIGIO DSP daughter card support" - default N ---help--- Enable support for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card @@ -406,7 +431,6 @@ config COMEDI_C6XDIGIO config COMEDI_MPC624 tristate "Micro/sys MPC-624 PC/104 board support" - default N ---help--- Enable support for Micro/sys MPC-624 PC/104 board @@ -415,7 +439,6 @@ config COMEDI_MPC624 config COMEDI_ADQ12B tristate "MicroAxial ADQ12-B data acquisition and control card support" - default N ---help--- Enable MicroAxial ADQ12-B daq and control card support. @@ -426,7 +449,6 @@ config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" depends on COMEDI_NI_COMMON depends on VIRT_TO_BUS - default N ---help--- Enable support for National Instruments AT-A2150 cards @@ -436,7 +458,6 @@ config COMEDI_NI_AT_A2150 config COMEDI_NI_AT_AO tristate "NI AT-AO-6/10 EISA card support" depends on COMEDI_NI_COMMON - default N ---help--- Enable support for National Instruments AT-AO-6/10 cards @@ -447,7 +468,6 @@ config COMEDI_NI_ATMIO tristate "NI AT-MIO E series ISA-PNP card support" depends on ISAPNP && COMEDI_NI_TIO && COMEDI_NI_COMMON select COMEDI_8255 - default N ---help--- Enable support for National Instruments AT-MIO E series cards National Instruments AT-MIO-16E-1 (ni_atmio), @@ -461,7 +481,6 @@ config COMEDI_NI_ATMIO16D tristate "NI AT-MIO16/AT-MIO16D series ISA-PNP card support" depends on ISAPNP && COMEDI_NI_COMMON select COMEDI_8255 - default N ---help--- Enable support for National Instruments AT-MIO16/AT-MIO16D cards. @@ -470,7 +489,6 @@ config COMEDI_NI_ATMIO16D config COMEDI_PCMAD tristate "Winsystems PCM-A/D12 and PCM-A/D16 PC/104 board support" - default N ---help--- Enable support for Winsystems PCM-A/D12 and PCM-A/D16 PC/104 boards. @@ -479,7 +497,6 @@ config COMEDI_PCMAD config COMEDI_PCMDA12 tristate "Winsystems PCM-D/A-12 8-channel AO PC/104 board support" - default N ---help--- Enable support for Winsystems PCM-D/A-12 8-channel AO PC/104 boards. Note that the board is not ISA-PNP capable and thus needs the I/O @@ -490,7 +507,6 @@ config COMEDI_PCMDA12 config COMEDI_PCMMIO tristate "Winsystems PCM-MIO PC/104 board support" - default N ---help--- Enable support for Winsystems PCM-MIO multifunction PC/104 boards. @@ -499,7 +515,6 @@ config COMEDI_PCMMIO config COMEDI_PCMUIO tristate "Winsystems PCM-UIO48A and PCM-UIO96A PC/104 board support" - default N ---help--- Enable support for PCM-UIO48A and PCM-UIO96A PC/104 boards. @@ -508,7 +523,6 @@ config COMEDI_PCMUIO config COMEDI_MULTIQ3 tristate "Quanser Consulting MultiQ-3 ISA card support" - default N ---help--- Enable support for Quanser Consulting MultiQ-3 ISA cards @@ -517,7 +531,6 @@ config COMEDI_MULTIQ3 config COMEDI_POC tristate "Generic driver for very simple devices" - default N ---help--- Enable generic support for very simple / POC (Piece of Crap) boards, Keithley Metrabyte DAC-02 (dac02), Advantech PCL-733 (pcl733) and @@ -531,7 +544,6 @@ endif # COMEDI_ISA_DRIVERS menuconfig COMEDI_PCI_DRIVERS tristate "Comedi PCI drivers" depends on COMEDI && PCI - default N ---help--- Enable comedi PCI drivers to be built @@ -544,7 +556,6 @@ if COMEDI_PCI_DRIVERS && PCI config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_035 cards @@ -554,7 +565,6 @@ config COMEDI_ADDI_APCI_035 config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_1032 cards @@ -564,7 +574,6 @@ config COMEDI_ADDI_APCI_1032 config COMEDI_ADDI_APCI_1500 tristate "ADDI-DATA APCI_1500 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_1500 cards @@ -574,7 +583,6 @@ config COMEDI_ADDI_APCI_1500 config COMEDI_ADDI_APCI_1516 tristate "ADDI-DATA APCI_1516 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_1516 cards @@ -584,7 +592,6 @@ config COMEDI_ADDI_APCI_1516 config COMEDI_ADDI_APCI_1564 tristate "ADDI-DATA APCI_1564 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_1564 cards @@ -594,7 +601,6 @@ config COMEDI_ADDI_APCI_1564 config COMEDI_ADDI_APCI_16XX tristate "ADDI-DATA APCI_16xx support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_16xx cards @@ -604,7 +610,6 @@ config COMEDI_ADDI_APCI_16XX config COMEDI_ADDI_APCI_2016 tristate "ADDI-DATA APCI_2016 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_2016 cards @@ -614,7 +619,6 @@ config COMEDI_ADDI_APCI_2016 config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_2032 cards @@ -624,7 +628,6 @@ config COMEDI_ADDI_APCI_2032 config COMEDI_ADDI_APCI_2200 tristate "ADDI-DATA APCI_2200 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_2200 cards @@ -635,7 +638,6 @@ config COMEDI_ADDI_APCI_3001 tristate "ADDI-DATA APCI_3001 support" depends on VIRT_TO_BUS select COMEDI_FC - default N ---help--- Enable support for ADDI-DATA APCI_3001 cards @@ -646,7 +648,6 @@ config COMEDI_ADDI_APCI_3120 tristate "ADDI-DATA APCI_3520 support" depends on VIRT_TO_BUS select COMEDI_FC - default N ---help--- Enable support for ADDI-DATA APCI_3520 cards @@ -656,7 +657,6 @@ config COMEDI_ADDI_APCI_3120 config COMEDI_ADDI_APCI_3501 tristate "ADDI-DATA APCI_3501 support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_3501 cards @@ -666,7 +666,6 @@ config COMEDI_ADDI_APCI_3501 config COMEDI_ADDI_APCI_3XXX tristate "ADDI-DATA APCI_3xxx support" depends on VIRT_TO_BUS - default N ---help--- Enable support for ADDI-DATA APCI_3xxx cards @@ -676,7 +675,6 @@ config COMEDI_ADDI_APCI_3XXX config COMEDI_ADL_PCI6208 tristate "ADLink PCI-6208A support" select COMEDI_8255 - default N ---help--- Enable support for ADLink PCI-6208A cards @@ -685,7 +683,6 @@ config COMEDI_ADL_PCI6208 config COMEDI_ADL_PCI7230 tristate "ADLink PCI-7230 digital io board support" - default N ---help--- Enable support for ADlink PCI-7230 digital io board support @@ -694,7 +691,6 @@ config COMEDI_ADL_PCI7230 config COMEDI_ADL_PCI7296 tristate "ADLink PCI-7296 96 ch. digital io board support" - default N ---help--- Enable support for ADlink PCI-7296 96 ch. digital io board support @@ -703,7 +699,6 @@ config COMEDI_ADL_PCI7296 config COMEDI_ADL_PCI7432 tristate "ADLink PCI-7432 64 ch. isolated digital io board support" - default N ---help--- Enable support for ADlink PCI-7432 64 ch. isolated digital io board @@ -712,7 +707,6 @@ config COMEDI_ADL_PCI7432 config COMEDI_ADL_PCI8164 tristate "ADLink PCI-8164 4 Axes Motion Control board support" - default N ---help--- Enable support for ADlink PCI-8164 4 Axes Motion Control board @@ -722,7 +716,6 @@ config COMEDI_ADL_PCI8164 config COMEDI_ADL_PCI9111 tristate "ADLink PCI-9111HR support" select COMEDI_FC - default N ---help--- Enable support for ADlink PCI9111 cards @@ -733,7 +726,6 @@ config COMEDI_ADL_PCI9118 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" select COMEDI_FC depends on VIRT_TO_BUS - default N ---help--- Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards @@ -742,7 +734,6 @@ config COMEDI_ADL_PCI9118 config COMEDI_ADV_PCI1710 tristate "Advantech PCI-171x, PCI-1720 and PCI-1731 support" - default N ---help--- Enable support for Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720 and PCI-1731 @@ -752,7 +743,6 @@ config COMEDI_ADV_PCI1710 config COMEDI_ADV_PCI1723 tristate "Advantech PCI-1723 support" - default N ---help--- Enable support for Advantech PCI-1723 cards @@ -762,7 +752,6 @@ config COMEDI_ADV_PCI1723 config COMEDI_ADV_PCI_DIO tristate "Advantech PCI DIO card support" select COMEDI_8255 - default N ---help--- Enable support for Advantech PCI DIO cards PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, @@ -772,31 +761,29 @@ config COMEDI_ADV_PCI_DIO To compile this driver as a module, choose M here: the module will be called adv_pci_dio. -config COMEDI_AMPLC_DIO200 - tristate "Amplicon PC272E and PCI272 DIO board support" - select COMEDI_8255 - default N +config COMEDI_AMPLC_DIO200_PCI + tristate "Amplicon PCI215 and PCI272 DIO board support" + select COMEDI_AMPLC_DIO200 ---help--- - Enable support for Amplicon PC272E and PCI272 DIO boards + Enable support for Amplicon PCI215 and PCI272 DIO boards. To compile this driver as a module, choose M here: the module will be called amplc_dio200. -config COMEDI_AMPLC_PC236 - tristate "Amplicon PC36AT and PCI236 DIO board support" - select COMEDI_8255 - default N +config COMEDI_AMPLC_PC236_PCI + tristate "Amplicon PCI236 DIO board support" + select COMEDI_AMPLC_PC236 ---help--- - Enable support for Amplicon PC36AT and PCI236 DIO boards + Enable support for Amplicon PCI236 DIO board. To compile this driver as a module, choose M here: the module will be called amplc_pc236. -config COMEDI_AMPLC_PC263 - tristate "Amplicon PC263 and PCI263 relay board support" - default N +config COMEDI_AMPLC_PC263_PCI + tristate "Amplicon PCI263 relay board support" + select COMEDI_AMPLC_PC263 ---help--- - Enable support for Amplicon PC263 and PCI263 relay boards + Enable support for Amplicon PCI263 relay board. To compile this driver as a module, choose M here: the module will be called amplc_pc263. @@ -804,7 +791,6 @@ config COMEDI_AMPLC_PC263 config COMEDI_AMPLC_PCI224 tristate "Amplicon PCI224 and PCI234 support" select COMEDI_FC - default N ---help--- Enable support for Amplicon PCI224 and PCI234 AO boards @@ -814,7 +800,6 @@ config COMEDI_AMPLC_PCI224 config COMEDI_AMPLC_PCI230 tristate "Amplicon PCI230 and PCI260 support" select COMEDI_8255 - default N ---help--- Enable support for Amplicon PCI230 and PCI260 Multifunction I/O boards @@ -824,16 +809,23 @@ config COMEDI_AMPLC_PCI230 config COMEDI_CONTEC_PCI_DIO tristate "Contec PIO1616L digital I/O board support" - default N ---help--- Enable support for the Contec PIO1616L digital I/O board To compile this driver as a module, choose M here: the module will be called contec_pci_dio. +config COMEDI_DAS08_PCI + tristate "DAS-08 PCI support" + select COMEDI_DAS08 + ---help--- + Enable support for PCI DAS-08 cards. + + To compile this driver as a module, choose M here: the module will be + called das08. + config COMEDI_DT3000 tristate "Data Translation DT3000 series support" - default N ---help--- Enable support for Data Translation DT3000 series DT3001, DT3001-PGL, DT3002, DT3003, DT3003-PGL, DT3004, DT3005 and @@ -844,7 +836,6 @@ config COMEDI_DT3000 config COMEDI_DYNA_PCI10XX tristate "Dynalog PCI DAQ series support" - default N ---help--- Enable support for Dynalog PCI DAQ series PCI-1050 @@ -854,7 +845,6 @@ config COMEDI_DYNA_PCI10XX config COMEDI_UNIOXX5 tristate "Fastwel UNIOxx-5 analog and digital io board support" - default N ---help--- Enable support for Fastwel UNIOxx-5 (analog and digital i/o) boards @@ -864,7 +854,6 @@ config COMEDI_UNIOXX5 config COMEDI_GSC_HPDI tristate "General Standards PCI-HPDI32 / PMC-HPDI32 support" select COMEDI_FC - default N ---help--- Enable support for General Standards Corporation high speed parallel digital interface rs485 boards PCI-HPDI32 and PMC-HPDI32. @@ -875,7 +864,6 @@ config COMEDI_GSC_HPDI config COMEDI_ICP_MULTI tristate "Inova ICP_MULTI support" - default N ---help--- Enable support for Inova ICP_MULTI card @@ -884,7 +872,6 @@ config COMEDI_ICP_MULTI config COMEDI_II_PCI20KC tristate "Intelligent Instruments PCI-20001C carrier support" - default N ---help--- Enable support for Intelligent Instruments PCI-20001C carrier PCI-20001, PCI-20006 and PCI-20341 @@ -895,7 +882,6 @@ config COMEDI_II_PCI20KC config COMEDI_DAQBOARD2000 tristate "IOtech DAQboard/2000 support" select COMEDI_8255 - default N ---help--- Enable support for the IOtech DAQboard/2000 @@ -904,7 +890,6 @@ config COMEDI_DAQBOARD2000 config COMEDI_JR3_PCI tristate "JR3/PCI force sensor board support" - default N ---help--- Enable support for JR3/PCI force sensor boards @@ -913,7 +898,6 @@ config COMEDI_JR3_PCI config COMEDI_KE_COUNTER tristate "Kolter-Electronic PCI Counter 1 card support" - default N ---help--- Enable support for Kolter-Electronic PCI Counter 1 cards @@ -924,7 +908,6 @@ config COMEDI_CB_PCIDAS64 tristate "MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 support" select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCI-DAS 64xx, 60xx, and 4020 series with the PLX 9080 PCI controller @@ -936,7 +919,6 @@ config COMEDI_CB_PCIDAS tristate "MeasurementComputing PCI-DAS support" select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCI-DAS with AMCC S5933 PCIcontroller: PCI-DAS1602/16, PCI-DAS1602/16jr, @@ -949,7 +931,6 @@ config COMEDI_CB_PCIDAS config COMEDI_CB_PCIDDA tristate "MeasurementComputing PCI-DDA series support" select COMEDI_8255 - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCI-DDA series: PCI-DDA08/12, PCI-DDA04/12, PCI-DDA02/12, PCI-DDA08/16, @@ -961,7 +942,6 @@ config COMEDI_CB_PCIDDA config COMEDI_CB_PCIDIO tristate "MeasurementComputing PCI-DIO series support" select COMEDI_8255 - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCI-DIO series PCI-DIO24, PCI-DIO24H and PCI-DIO48H @@ -972,7 +952,6 @@ config COMEDI_CB_PCIDIO config COMEDI_CB_PCIMDAS tristate "MeasurementComputing PCIM-DAS1602/16 support" select COMEDI_8255 - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCI Migration series PCIM-DAS1602/16 @@ -983,7 +962,6 @@ config COMEDI_CB_PCIMDAS config COMEDI_CB_PCIMDDA tristate "MeasurementComputing PCIM-DDA06-16 support" select COMEDI_8255 - default N ---help--- Enable support for ComputerBoards/MeasurementComputing PCIM-DDA06-16 @@ -992,7 +970,6 @@ config COMEDI_CB_PCIMDDA config COMEDI_ME4000 tristate "Meilhaus ME-4000 support" - default N ---help--- Enable support for Meilhaus PCI data acquisition cards ME-4650, ME-4670i, ME-4680, ME-4680i and ME-4680is @@ -1002,7 +979,6 @@ config COMEDI_ME4000 config COMEDI_ME_DAQ tristate "Meilhaus ME-2000i, ME-2600i, ME-3000vm1 support" - default N ---help--- Enable support for Meilhaus PCI data acquisition cards ME-2000i, ME-2600i and ME-3000vm1 @@ -1013,7 +989,6 @@ config COMEDI_ME_DAQ config COMEDI_NI_6527 tristate "NI 6527 support" depends on COMEDI_MITE - default N ---help--- Enable support for the National Instruments 6527 PCI card @@ -1023,7 +998,6 @@ config COMEDI_NI_6527 config COMEDI_NI_65XX tristate "NI 65xx static dio PCI card support" depends on COMEDI_MITE - default N ---help--- Enable support for National Instruments 65xx static dio boards. Supported devices: National Instruments PCI-6509 (ni_65xx), @@ -1037,7 +1011,6 @@ config COMEDI_NI_65XX config COMEDI_NI_660X tristate "NI 660x counter/timer PCI card support" depends on COMEDI_NI_TIO && COMEDI_NI_COMMON - default N ---help--- Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602, PXI-6602 and PXI-6608. @@ -1048,7 +1021,6 @@ config COMEDI_NI_660X config COMEDI_NI_670X tristate "NI 670x PCI card support" depends on COMEDI_MITE - default N ---help--- Enable support for National Instruments PCI-6703 and PCI-6704 @@ -1059,7 +1031,6 @@ config COMEDI_NI_PCIDIO tristate "NI PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503 support" depends on COMEDI_MITE select COMEDI_8255 - default N ---help--- Enable support for National Instruments PCI-DIO-32HS, PXI-6533, PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X, @@ -1075,7 +1046,6 @@ config COMEDI_NI_PCIMIO depends on COMEDI_NI_TIO && COMEDI_NI_COMMON select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for National Instruments PCI-MIO-E series and M series (all boards): PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, @@ -1094,7 +1064,6 @@ config COMEDI_NI_PCIMIO config COMEDI_RTD520 tristate "Real Time Devices PCI4520/DM7520 support" select COMEDI_8255 - default N ---help--- Enable support for Real Time Devices PCI4520/DM7520 @@ -1103,7 +1072,6 @@ config COMEDI_RTD520 config COMEDI_S526 tristate "Sensoray s526 support" - default N ---help--- Enable support for Sensoray s526 @@ -1113,7 +1081,6 @@ config COMEDI_S526 config COMEDI_S626 tristate "Sensoray 626 support" select COMEDI_FC - default N ---help--- Enable support for Sensoray 626 @@ -1122,7 +1089,6 @@ config COMEDI_S626 config COMEDI_SSV_DNP tristate "SSV Embedded Systems DIL/Net-PC support" - default N ---help--- Enable support for SSV Embedded Systems DIL/Net-PC @@ -1134,7 +1100,6 @@ endif # COMEDI_PCI_DRIVERS menuconfig COMEDI_PCMCIA_DRIVERS tristate "Comedi PCMCIA drivers" depends on COMEDI && (PCMCIA || PCCARD) - default N ---help--- Enable comedi PCMCIA and PCCARD drivers to be built @@ -1146,7 +1111,6 @@ if COMEDI_PCMCIA_DRIVERS && PCMCIA config COMEDI_CB_DAS16_CS tristate "CB DAS16 series PCMCIA support" - default N ---help--- Enable support for the ComputerBoards/MeasurementComputing PCMCIA cards DAS16/16, PCM-DAS16D/12 and PCM-DAS16s/16 @@ -1157,7 +1121,6 @@ config COMEDI_CB_DAS16_CS config COMEDI_DAS08_CS tristate "CB DAS08 PCMCIA support" select COMEDI_DAS08 - default N ---help--- Enable support for the ComputerBoards/MeasurementComputing DAS-08 PCMCIA card @@ -1168,7 +1131,6 @@ config COMEDI_DAS08_CS config COMEDI_NI_DAQ_700_CS tristate "NI DAQCard-700 PCMCIA support" depends on COMEDI_NI_COMMON - default N ---help--- Enable support for the National Instruments PCMCIA DAQCard-700 DIO @@ -1179,7 +1141,6 @@ config COMEDI_NI_DAQ_DIO24_CS tristate "NI DAQ-Card DIO-24 PCMCIA support" depends on COMEDI_NI_COMMON select COMEDI_8255 - default N ---help--- Enable support for the National Instruments PCMCIA DAQ-Card DIO-24 @@ -1189,7 +1150,6 @@ config COMEDI_NI_DAQ_DIO24_CS config COMEDI_NI_LABPC_CS tristate "NI DAQCard-1200 PCMCIA support" depends on COMEDI_NI_LABPC - default N ---help--- Enable support for the National Instruments PCMCIA DAQCard-1200 @@ -1201,7 +1161,6 @@ config COMEDI_NI_MIO_CS depends on COMEDI_NI_TIO && COMEDI_NI_COMMON select COMEDI_8255 select COMEDI_FC - default N ---help--- Enable support for the National Instruments PCMCIA DAQCard E series DAQCard-ai-16xe-50, DAQCard-ai-16e-4, DAQCard-6062E, DAQCard-6024E @@ -1212,7 +1171,6 @@ config COMEDI_NI_MIO_CS config COMEDI_QUATECH_DAQP_CS tristate "Quatech DAQP PCMCIA data capture card support" - default N ---help--- Enable support for the Quatech DAQP PCMCIA data capture cards DAQP-208 and DAQP-308 @@ -1225,7 +1183,6 @@ endif # COMEDI_PCMCIA_DRIVERS menuconfig COMEDI_USB_DRIVERS tristate "Comedi USB drivers" depends on COMEDI && USB - default N ---help--- Enable comedi USB drivers to be built @@ -1237,7 +1194,6 @@ if COMEDI_USB_DRIVERS && USB config COMEDI_DT9812 tristate "DataTranslation DT9812 USB module support" - default N ---help--- Enable support for the Data Translation DT9812 USB module @@ -1246,7 +1202,6 @@ config COMEDI_DT9812 config COMEDI_USBDUX tristate "ITL USB-DUX-D support" - default N ---help--- Enable support for the Incite Technology Ltd USB-DUX-D Board @@ -1256,7 +1211,6 @@ config COMEDI_USBDUX config COMEDI_USBDUXFAST tristate "ITL USB-DUXfast support" select COMEDI_FC - default N ---help--- Enable support for the Incite Technology Ltd USB-DUXfast Board @@ -1266,7 +1220,6 @@ config COMEDI_USBDUXFAST config COMEDI_USBDUXSIGMA tristate "ITL USB-DUXsigma support" select COMEDI_FC - default N ---help--- Enable support for the Incite Technology Ltd USB-DUXsigma Board @@ -1275,7 +1228,6 @@ config COMEDI_USBDUXSIGMA config COMEDI_VMK80XX tristate "Velleman VM110/VM140 USB Board support" - default N ---help--- Build the Velleman USB Board Low-Level Driver supporting the K8055/K8061 aka VM110/VM140 devices @@ -1288,7 +1240,6 @@ endif # COMEDI_USB_DRIVERS menuconfig COMEDI_NI_COMMON tristate "Comedi National Instruments card support" depends on COMEDI - default N ---help--- Enable comedi support for National Instruments cards. Modules in this section are used by many comedi NI drivers. @@ -1302,7 +1253,6 @@ if COMEDI_NI_COMMON config COMEDI_MITE tristate "NI Mite PCI interface chip support" depends on PCI - default N ---help--- Enable support for National Instruments Mite PCI interface chip @@ -1312,7 +1262,6 @@ config COMEDI_MITE config COMEDI_NI_TIO tristate "NI general purpose counter support" depends on COMEDI_MITE - default N ---help--- Enable support for National Instruments general purpose counters. This module is not used directly by end-users. Rather, it @@ -1328,7 +1277,6 @@ config COMEDI_NI_LABPC select COMEDI_8255 select COMEDI_FC depends on VIRT_TO_BUS - default N ---help--- Enable support for National Instruments Lab-PC and compatibles Lab-PC-1200, Lab-PC-1200AI, Lab-PC+ and PCI-1200. @@ -1343,7 +1291,6 @@ endif # COMEDI_NI_COMMON config COMEDI_8255 tristate "Generic 8255 support" depends on COMEDI - default N ---help--- Enable generic 8255 support. @@ -1357,24 +1304,9 @@ config COMEDI_8255 To compile this driver as a module, choose M here: the module will be called 8255. -config COMEDI_DAS08 - tristate "DAS-08 compatible support" - depends on COMEDI - select COMEDI_8255 - default N - ---help--- - Enable support for DAS08 and compatible ISA, PC/104 and PCI cards. - - Note that PCMCIA DAS08 cards are not directly supported by this - driver, and need a separate driver as a wrapper. - - To compile this driver as a module, choose M here: the module will be - called das08. - config COMEDI_FC tristate "Comedi shared functions for low-level driver support" depends on COMEDI - default N ---help--- Enable support for shared functions for low-level drivers. This module is not used directly by end-users. Rather, it @@ -1382,3 +1314,22 @@ config COMEDI_FC To compile this driver as a module, choose M here: the module will be called comedi_fc. + +config COMEDI_AMPLC_DIO200 + tristate + depends on COMEDI + select COMEDI_8255 + +config COMEDI_AMPLC_PC236 + tristate + depends on COMEDI + select COMEDI_8255 + +config COMEDI_AMPLC_PC263 + tristate + depends on COMEDI + +config COMEDI_DAS08 + tristate + depends on COMEDI + select COMEDI_8255 diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 14ea35a..8ea55ae 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -465,7 +465,7 @@ /* only relevant to kernel modules. */ #define COMEDI_CB_EOS 1 /* end of scan */ -#define COMEDI_CB_EOA 2 /* end of acquisition */ +#define COMEDI_CB_EOA 2 /* end of acquisition/output */ #define COMEDI_CB_BLOCK 4 /* data has arrived: * wakes up read() / write() */ #define COMEDI_CB_EOBUF 8 /* DEPRECATED: end of buffer */ diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9bcf87a..7677657 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -58,14 +58,35 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; EXPORT_SYMBOL(comedi_debug); -module_param(comedi_debug, int, 0644); +module_param(comedi_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_debug, + "enable comedi core and driver debugging if non-zero (default 0)" + ); #endif bool comedi_autoconfig = 1; -module_param(comedi_autoconfig, bool, 0444); +module_param(comedi_autoconfig, bool, S_IRUGO); +MODULE_PARM_DESC(comedi_autoconfig, + "enable drivers to auto-configure comedi devices (default 1)"); static int comedi_num_legacy_minors; -module_param(comedi_num_legacy_minors, int, 0444); +module_param(comedi_num_legacy_minors, int, S_IRUGO); +MODULE_PARM_DESC(comedi_num_legacy_minors, + "number of comedi minor devices to reserve for non-auto-configured devices (default 0)" + ); + +unsigned int comedi_default_buf_size_kb = CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB; +module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_size_kb, + "default asynchronous buffer size in KiB (default " + __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB) ")"); + +unsigned int comedi_default_buf_maxsize_kb + = CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB; +module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(comedi_default_buf_maxsize_kb, + "default maximum size of asynchronous buffer in KiB (default " + __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")"); static DEFINE_SPINLOCK(comedi_file_info_table_lock); static struct comedi_device_file_info @@ -108,15 +129,283 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int comedi_fasync(int fd, struct file *file, int on); static int is_device_busy(struct comedi_device *dev); + static int resize_async_buffer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_async *async, unsigned new_size); + struct comedi_async *async, unsigned new_size) +{ + int retval; + + if (new_size > async->max_bufsize) + return -EPERM; + + if (s->busy) { + DPRINTK("subdevice is busy, cannot resize buffer\n"); + return -EBUSY; + } + if (async->mmap_count) { + DPRINTK("subdevice is mmapped, cannot resize buffer\n"); + return -EBUSY; + } + + if (!async->prealloc_buf) + return -EINVAL; + + /* make sure buffer is an integral number of pages + * (we round up) */ + new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; + + retval = comedi_buf_alloc(dev, s, new_size); + if (retval < 0) + return retval; + + if (s->buf_change) { + retval = s->buf_change(dev, s, new_size); + if (retval < 0) + return retval; + } + + DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", + dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz); + return 0; +} + +/* sysfs attribute files */ + +static const unsigned bytes_per_kibi = 1024; + +static ssize_t show_max_read_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned max_buffer_size_kb = 0; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + mutex_lock(&info->device->mutex); + if (read_subdevice && + (read_subdevice->subdev_flags & SDF_CMD_READ) && + read_subdevice->async) { + max_buffer_size_kb = read_subdevice->async->max_bufsize / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_max_read_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_max_size_kb; + unsigned int new_max_size; + int ret; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + ret = kstrtouint(buf, 10, &new_max_size_kb); + if (ret) + return ret; + if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_max_size = new_max_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (read_subdevice == NULL || + (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || + read_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + read_subdevice->async->max_bufsize = new_max_size; + mutex_unlock(&info->device->mutex); + + return count; +} + +static ssize_t show_read_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned buffer_size_kb = 0; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + mutex_lock(&info->device->mutex); + if (read_subdevice && + (read_subdevice->subdev_flags & SDF_CMD_READ) && + read_subdevice->async) { + buffer_size_kb = read_subdevice->async->prealloc_bufsz / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_read_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_size_kb; + unsigned int new_size; + int retval; + int ret; + struct comedi_subdevice *const read_subdevice = + comedi_get_read_subdevice(info); + + ret = kstrtouint(buf, 10, &new_size_kb); + if (ret) + return ret; + if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_size = new_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (read_subdevice == NULL || + (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || + read_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + retval = resize_async_buffer(info->device, read_subdevice, + read_subdevice->async, new_size); + mutex_unlock(&info->device->mutex); + + if (retval < 0) + return retval; + return count; +} + +static ssize_t show_max_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned max_buffer_size_kb = 0; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + mutex_lock(&info->device->mutex); + if (write_subdevice && + (write_subdevice->subdev_flags & SDF_CMD_WRITE) && + write_subdevice->async) { + max_buffer_size_kb = write_subdevice->async->max_bufsize / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); + mutex_unlock(&info->device->mutex); + + return retval; +} + +static ssize_t store_max_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_max_size_kb; + unsigned int new_max_size; + int ret; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + ret = kstrtouint(buf, 10, &new_max_size_kb); + if (ret) + return ret; + if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_max_size = new_max_size_kb * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (write_subdevice == NULL || + (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || + write_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + write_subdevice->async->max_bufsize = new_max_size; + mutex_unlock(&info->device->mutex); + + return count; +} + +static ssize_t show_write_buffer_kb(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t retval; + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned buffer_size_kb = 0; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + mutex_lock(&info->device->mutex); + if (write_subdevice && + (write_subdevice->subdev_flags & SDF_CMD_WRITE) && + write_subdevice->async) { + buffer_size_kb = write_subdevice->async->prealloc_bufsz / + bytes_per_kibi; + } + retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); + mutex_unlock(&info->device->mutex); -/* declarations for sysfs attribute files */ -static struct device_attribute dev_attr_max_read_buffer_kb; -static struct device_attribute dev_attr_read_buffer_kb; -static struct device_attribute dev_attr_max_write_buffer_kb; -static struct device_attribute dev_attr_write_buffer_kb; + return retval; +} + +static ssize_t store_write_buffer_kb(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct comedi_device_file_info *info = dev_get_drvdata(dev); + unsigned int new_size_kb; + unsigned int new_size; + int retval; + int ret; + struct comedi_subdevice *const write_subdevice = + comedi_get_write_subdevice(info); + + ret = kstrtouint(buf, 10, &new_size_kb); + if (ret) + return ret; + if (new_size_kb > (UINT_MAX / bytes_per_kibi)) + return -EINVAL; + new_size = ((uint64_t) new_size_kb) * bytes_per_kibi; + + mutex_lock(&info->device->mutex); + if (write_subdevice == NULL || + (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || + write_subdevice->async == NULL) { + mutex_unlock(&info->device->mutex); + return -EINVAL; + } + retval = resize_async_buffer(info->device, write_subdevice, + write_subdevice->async, new_size); + mutex_unlock(&info->device->mutex); + + if (retval < 0) + return retval; + return count; +} + +static struct device_attribute comedi_dev_attrs[] = { + __ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, + show_max_read_buffer_kb, store_max_read_buffer_kb), + __ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_read_buffer_kb, store_read_buffer_kb), + __ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, + show_max_write_buffer_kb, store_max_write_buffer_kb), + __ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, + show_write_buffer_kb, store_write_buffer_kb), + __ATTR_NULL +}; static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -280,7 +569,7 @@ static int do_devconfig_ioctl(struct comedi_device *dev, if (ret == 0) { if (!try_module_get(dev->driver->module)) { comedi_device_detach(dev); - return -ENOSYS; + ret = -ENOSYS; } } @@ -1545,7 +1834,7 @@ done: return retval; } -static unsigned int comedi_poll(struct file *file, poll_table * wait) +static unsigned int comedi_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; const unsigned minor = iminor(file->f_dentry->d_inode); @@ -2054,6 +2343,8 @@ static int __init comedi_init(void) return PTR_ERR(comedi_class); } + comedi_class->dev_attrs = comedi_dev_attrs; + /* XXX requires /proc interface */ comedi_proc_init(); @@ -2192,11 +2483,9 @@ static void comedi_device_cleanup(struct comedi_device *dev) int comedi_alloc_board_minor(struct device *hardware_device) { - unsigned long flags; struct comedi_device_file_info *info; struct device *csdev; unsigned i; - int retval; info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); if (info == NULL) @@ -2206,15 +2495,16 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info); return -ENOMEM; } + info->hardware_device = hardware_device; comedi_device_init(info->device); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) { if (comedi_file_info_table[i] == NULL) { comedi_file_info_table[i] = info; break; } } - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_BOARD_MINORS) { comedi_device_cleanup(info->device); kfree(info->device); @@ -2230,55 +2520,19 @@ int comedi_alloc_board_minor(struct device *hardware_device) if (!IS_ERR(csdev)) info->device->class_dev = csdev; dev_set_drvdata(csdev, info); - retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_read_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_read_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_write_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } - retval = device_create_file(csdev, &dev_attr_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_write_buffer_kb.attr.name); - comedi_free_board_minor(i); - return retval; - } + return i; } void comedi_free_board_minor(unsigned minor) { - unsigned long flags; struct comedi_device_file_info *info; BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[minor]; comedi_file_info_table[minor] = NULL; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (info) { struct comedi_device *dev = info->device; @@ -2294,14 +2548,29 @@ void comedi_free_board_minor(unsigned minor) } } +int comedi_find_board_minor(struct device *hardware_device) +{ + int minor; + struct comedi_device_file_info *info; + + for (minor = 0; minor < COMEDI_NUM_BOARD_MINORS; minor++) { + spin_lock(&comedi_file_info_table_lock); + info = comedi_file_info_table[minor]; + if (info && info->hardware_device == hardware_device) { + spin_unlock(&comedi_file_info_table_lock); + return minor; + } + spin_unlock(&comedi_file_info_table_lock); + } + return -ENODEV; +} + int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned long flags; struct comedi_device_file_info *info; struct device *csdev; unsigned i; - int retval; info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL); if (info == NULL) @@ -2309,14 +2578,14 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, info->device = dev; info->read_subdevice = s; info->write_subdevice = s; - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) { if (comedi_file_info_table[i] == NULL) { comedi_file_info_table[i] = info; break; } } - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_MINORS) { kfree(info); printk(KERN_ERR @@ -2331,48 +2600,12 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, if (!IS_ERR(csdev)) s->class_dev = csdev; dev_set_drvdata(csdev, info); - retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_read_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; - } - retval = device_create_file(csdev, &dev_attr_read_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_read_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; - } - retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_max_write_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; - } - retval = device_create_file(csdev, &dev_attr_write_buffer_kb); - if (retval) { - printk(KERN_ERR - "comedi: " - "failed to create sysfs attribute file \"%s\".\n", - dev_attr_write_buffer_kb.attr.name); - comedi_free_subdevice_minor(s); - return retval; - } + return i; } void comedi_free_subdevice_minor(struct comedi_subdevice *s) { - unsigned long flags; struct comedi_device_file_info *info; if (s == NULL) @@ -2383,10 +2616,10 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) BUG_ON(s->minor >= COMEDI_NUM_MINORS); BUG_ON(s->minor < COMEDI_FIRST_SUBDEVICE_MINOR); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[s->minor]; comedi_file_info_table[s->minor] = NULL; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); if (s->class_dev) { device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor)); @@ -2397,310 +2630,12 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s) struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) { - unsigned long flags; struct comedi_device_file_info *info; BUG_ON(minor >= COMEDI_NUM_MINORS); - spin_lock_irqsave(&comedi_file_info_table_lock, flags); + spin_lock(&comedi_file_info_table_lock); info = comedi_file_info_table[minor]; - spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); + spin_unlock(&comedi_file_info_table_lock); return info; } EXPORT_SYMBOL_GPL(comedi_get_device_file_info); - -static int resize_async_buffer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_async *async, unsigned new_size) -{ - int retval; - - if (new_size > async->max_bufsize) - return -EPERM; - - if (s->busy) { - DPRINTK("subdevice is busy, cannot resize buffer\n"); - return -EBUSY; - } - if (async->mmap_count) { - DPRINTK("subdevice is mmapped, cannot resize buffer\n"); - return -EBUSY; - } - - if (!async->prealloc_buf) - return -EINVAL; - - /* make sure buffer is an integral number of pages - * (we round up) */ - new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK; - - retval = comedi_buf_alloc(dev, s, new_size); - if (retval < 0) - return retval; - - if (s->buf_change) { - retval = s->buf_change(dev, s, new_size); - if (retval < 0) - return retval; - } - - DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", - dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz); - return 0; -} - -/* sysfs attribute files */ - -static const unsigned bytes_per_kibi = 1024; - -static ssize_t show_max_read_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - max_buffer_size_kb = read_subdevice->async->max_bufsize / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); - mutex_unlock(&info->device->mutex); - - return retval; -} - -static ssize_t store_max_read_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; - - mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - read_subdevice->async->max_bufsize = new_max_size; - mutex_unlock(&info->device->mutex); - - return count; -} - -static struct device_attribute dev_attr_max_read_buffer_kb = { - .attr = { - .name = "max_read_buffer_kb", - .mode = S_IRUGO | S_IWUSR}, - .show = &show_max_read_buffer_kb, - .store = &store_max_read_buffer_kb -}; - -static ssize_t show_read_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - mutex_lock(&info->device->mutex); - if (read_subdevice && - (read_subdevice->subdev_flags & SDF_CMD_READ) && - read_subdevice->async) { - buffer_size_kb = read_subdevice->async->prealloc_bufsz / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); - mutex_unlock(&info->device->mutex); - - return retval; -} - -static ssize_t store_read_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const read_subdevice = - comedi_get_read_subdevice(info); - - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_size = new_size_kb * bytes_per_kibi; - - mutex_lock(&info->device->mutex); - if (read_subdevice == NULL || - (read_subdevice->subdev_flags & SDF_CMD_READ) == 0 || - read_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - retval = resize_async_buffer(info->device, read_subdevice, - read_subdevice->async, new_size); - mutex_unlock(&info->device->mutex); - - if (retval < 0) - return retval; - return count; -} - -static struct device_attribute dev_attr_read_buffer_kb = { - .attr = { - .name = "read_buffer_kb", - .mode = S_IRUGO | S_IWUSR | S_IWGRP}, - .show = &show_read_buffer_kb, - .store = &store_read_buffer_kb -}; - -static ssize_t show_max_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned max_buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - max_buffer_size_kb = write_subdevice->async->max_bufsize / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb); - mutex_unlock(&info->device->mutex); - - return retval; -} - -static ssize_t store_max_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_max_size_kb; - unsigned int new_max_size; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - ret = kstrtouint(buf, 10, &new_max_size_kb); - if (ret) - return ret; - if (new_max_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_max_size = new_max_size_kb * bytes_per_kibi; - - mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - write_subdevice->async->max_bufsize = new_max_size; - mutex_unlock(&info->device->mutex); - - return count; -} - -static struct device_attribute dev_attr_max_write_buffer_kb = { - .attr = { - .name = "max_write_buffer_kb", - .mode = S_IRUGO | S_IWUSR}, - .show = &show_max_write_buffer_kb, - .store = &store_max_write_buffer_kb -}; - -static ssize_t show_write_buffer_kb(struct device *dev, - struct device_attribute *attr, char *buf) -{ - ssize_t retval; - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned buffer_size_kb = 0; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - mutex_lock(&info->device->mutex); - if (write_subdevice && - (write_subdevice->subdev_flags & SDF_CMD_WRITE) && - write_subdevice->async) { - buffer_size_kb = write_subdevice->async->prealloc_bufsz / - bytes_per_kibi; - } - retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb); - mutex_unlock(&info->device->mutex); - - return retval; -} - -static ssize_t store_write_buffer_kb(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct comedi_device_file_info *info = dev_get_drvdata(dev); - unsigned int new_size_kb; - unsigned int new_size; - int retval; - int ret; - struct comedi_subdevice *const write_subdevice = - comedi_get_write_subdevice(info); - - ret = kstrtouint(buf, 10, &new_size_kb); - if (ret) - return ret; - if (new_size_kb > (UINT_MAX / bytes_per_kibi)) - return -EINVAL; - new_size = ((uint64_t) new_size_kb) * bytes_per_kibi; - - mutex_lock(&info->device->mutex); - if (write_subdevice == NULL || - (write_subdevice->subdev_flags & SDF_CMD_WRITE) == 0 || - write_subdevice->async == NULL) { - mutex_unlock(&info->device->mutex); - return -EINVAL; - } - retval = resize_async_buffer(info->device, write_subdevice, - write_subdevice->async, new_size); - mutex_unlock(&info->device->mutex); - - if (retval < 0) - return retval; - return count; -} - -static struct device_attribute dev_attr_write_buffer_kb = { - .attr = { - .name = "write_buffer_kb", - .mode = S_IRUGO | S_IWUSR | S_IWGRP}, - .show = &show_write_buffer_kb, - .store = &store_write_buffer_kb -}; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 7a0d4bc..134be93 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -180,13 +180,18 @@ struct comedi_async { unsigned int x); }; +struct pci_dev; +struct usb_interface; + struct comedi_driver { struct comedi_driver *next; const char *driver_name; struct module *module; int (*attach) (struct comedi_device *, struct comedi_devconfig *); - int (*detach) (struct comedi_device *); + void (*detach) (struct comedi_device *); + int (*attach_pci) (struct comedi_device *, struct pci_dev *); + int (*attach_usb) (struct comedi_device *, struct usb_interface *); /* number of elements in board_name and board_id arrays */ unsigned int num_names; @@ -230,10 +235,16 @@ struct comedi_device { void (*close) (struct comedi_device *dev); }; +static inline const void *comedi_board(struct comedi_device *dev) +{ + return dev->board_ptr; +} + struct comedi_device_file_info { struct comedi_device *device; struct comedi_subdevice *read_subdevice; struct comedi_subdevice *write_subdevice; + struct device *hardware_device; }; #ifdef CONFIG_COMEDI_DEBUG @@ -287,6 +298,56 @@ int comedi_device_attach(struct comedi_device *dev, int comedi_driver_register(struct comedi_driver *); int comedi_driver_unregister(struct comedi_driver *); +/** + * module_comedi_driver() - Helper macro for registering a comedi driver + * @__comedi_driver: comedi_driver struct + * + * Helper macro for comedi drivers which do not do anything special in module + * init/exit. This eliminates a lot of boilerplate. Each module may only use + * this macro once, and calling it replaces module_init() and module_exit(). + */ +#define module_comedi_driver(__comedi_driver) \ + module_driver(__comedi_driver, comedi_driver_register, \ + comedi_driver_unregister) + +struct pci_driver; + +int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *); +void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *); + +/** + * module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver + * @__comedi_driver: comedi_driver struct + * @__pci_driver: pci_driver struct + * + * Helper macro for comedi PCI drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_pci_driver(__comedi_driver, __pci_driver) \ + module_driver(__comedi_driver, comedi_pci_driver_register, \ + comedi_pci_driver_unregister, &(__pci_driver)) + +struct usb_driver; + +int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *); +void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *); + +/** + * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver + * @__comedi_driver: comedi_driver struct + * @__usb_driver: usb_driver struct + * + * Helper macro for comedi USB drivers which do not do anything special + * in module init/exit. This eliminates a lot of boilerplate. Each + * module may only use this macro once, and calling it replaces + * module_init() and module_exit() + */ +#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \ + module_driver(__comedi_driver, comedi_usb_driver_register, \ + comedi_usb_driver_unregister, &(__usb_driver)) + void init_polling(void); void cleanup_polling(void); void start_polling(struct comedi_device *); @@ -456,11 +517,12 @@ static inline void *comedi_aux_data(int options[], int n) int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_free_subdevice_minor(struct comedi_subdevice *s); -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name); +int comedi_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -struct usb_device; /* forward declaration */ -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); -void comedi_usb_auto_unconfig(struct usb_device *usbdev); +int comedi_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver); +void comedi_usb_auto_unconfig(struct usb_interface *intf); #ifdef CONFIG_COMEDI_PCI_DRIVERS #define CONFIG_COMEDI_PCI diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index bf185e2..1c3d638 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -106,6 +106,26 @@ void comedi_device_detach(struct comedi_device *dev) __comedi_device_detach(dev); } +/* do a little post-config cleanup */ +/* called with module refcount incremented, decrements it */ +static int comedi_device_postconfig(struct comedi_device *dev) +{ + int ret = postconfig(dev); + module_put(dev->driver->module); + if (ret < 0) { + __comedi_device_detach(dev); + return ret; + } + if (!dev->board_name) { + printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", + dev->board_name); + dev->board_name = "BUG"; + } + smp_wmb(); + dev->attached = 1; + return 0; +} + int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_driver *driv; @@ -121,59 +141,36 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) } if (driv->num_names) { dev->board_ptr = comedi_recognize(driv, it->board_name); - if (dev->board_ptr == NULL) { - module_put(driv->module); - continue; - } - } else { - if (strcmp(driv->driver_name, it->board_name)) { - module_put(driv->module); + if (dev->board_ptr) + break; + } else if (strcmp(driv->driver_name, it->board_name)) + break; + module_put(driv->module); + } + if (driv == NULL) { + /* recognize has failed if we get here */ + /* report valid board names before returning error */ + for (driv = comedi_drivers; driv; driv = driv->next) { + if (!try_module_get(driv->module)) { + printk(KERN_INFO + "comedi: failed to increment module count\n"); continue; } + comedi_report_boards(driv); + module_put(driv->module); } - /* initialize dev->driver here so - * comedi_error() can be called from attach */ - dev->driver = driv; - ret = driv->attach(dev, it); - if (ret < 0) { - module_put(dev->driver->module); - __comedi_device_detach(dev); - return ret; - } - goto attached; + return -EIO; } - - /* recognize has failed if we get here */ - /* report valid board names before returning error */ - for (driv = comedi_drivers; driv; driv = driv->next) { - if (!try_module_get(driv->module)) { - printk(KERN_INFO - "comedi: failed to increment module count\n"); - continue; - } - comedi_report_boards(driv); - module_put(driv->module); - } - return -EIO; - -attached: - /* do a little post-config cleanup */ - ret = postconfig(dev); - module_put(dev->driver->module); + /* initialize dev->driver here so + * comedi_error() can be called from attach */ + dev->driver = driv; + ret = driv->attach(dev, it); if (ret < 0) { + module_put(dev->driver->module); __comedi_device_detach(dev); return ret; } - - if (!dev->board_name) { - printk(KERN_WARNING "BUG: dev->board_name=<%p>\n", - dev->board_name); - dev->board_name = "BUG"; - } - smp_wmb(); - dev->attached = 1; - - return 0; + return comedi_device_postconfig(dev); } int comedi_driver_register(struct comedi_driver *driver) @@ -242,6 +239,8 @@ static int postconfig(struct comedi_device *dev) s->len_chanlist = 1; if (s->do_cmd) { + unsigned int buf_size; + BUG_ON((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0); BUG_ON(!s->do_cmdtest); @@ -257,19 +256,20 @@ static int postconfig(struct comedi_device *dev) async->subdevice = s; s->async = async; -#define DEFAULT_BUF_MAXSIZE (64*1024) -#define DEFAULT_BUF_SIZE (64*1024) - - async->max_bufsize = DEFAULT_BUF_MAXSIZE; + async->max_bufsize = + comedi_default_buf_maxsize_kb * 1024; + buf_size = comedi_default_buf_size_kb * 1024; + if (buf_size > async->max_bufsize) + buf_size = async->max_bufsize; async->prealloc_buf = NULL; async->prealloc_bufsz = 0; - if (comedi_buf_alloc(dev, s, DEFAULT_BUF_SIZE) < 0) { + if (comedi_buf_alloc(dev, s, buf_size) < 0) { printk(KERN_INFO "Buffer allocation failed\n"); return -ENOMEM; } if (s->buf_change) { - ret = s->buf_change(dev, s, DEFAULT_BUF_SIZE); + ret = s->buf_change(dev, s, buf_size); if (ret < 0) return ret; } @@ -814,67 +814,102 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } -static int comedi_auto_config(struct device *hardware_device, - const char *board_name, const int *options, - unsigned num_options) +static int +comedi_auto_config_helper(struct device *hardware_device, + struct comedi_driver *driver, + int (*attach_wrapper) (struct comedi_device *, + void *), void *context) { - struct comedi_devconfig it; int minor; struct comedi_device_file_info *dev_file_info; - int retval; - unsigned *private_data = NULL; + struct comedi_device *comedi_dev; + int ret; - if (!comedi_autoconfig) { - dev_set_drvdata(hardware_device, NULL); + if (!comedi_autoconfig) return 0; - } minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; - private_data = kmalloc(sizeof(unsigned), GFP_KERNEL); - if (private_data == NULL) { - retval = -ENOMEM; - goto cleanup; + dev_file_info = comedi_get_device_file_info(minor); + comedi_dev = dev_file_info->device; + + mutex_lock(&comedi_dev->mutex); + if (comedi_dev->attached) + ret = -EBUSY; + else if (!try_module_get(driver->module)) { + printk(KERN_INFO "comedi: failed to increment module count\n"); + ret = -EIO; + } else { + /* set comedi_dev->driver here for attach wrapper */ + comedi_dev->driver = driver; + ret = (*attach_wrapper)(comedi_dev, context); + if (ret < 0) { + module_put(driver->module); + __comedi_device_detach(comedi_dev); + } else { + ret = comedi_device_postconfig(comedi_dev); + } } - *private_data = minor; - dev_set_drvdata(hardware_device, private_data); + mutex_unlock(&comedi_dev->mutex); - dev_file_info = comedi_get_device_file_info(minor); + if (ret < 0) + comedi_free_board_minor(minor); + return ret; +} + +static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) +{ + struct comedi_devconfig *it = context; + struct comedi_driver *driv = dev->driver; + + if (driv->num_names) { + /* look for generic board entry matching driver name, which + * has already been copied to it->board_name */ + dev->board_ptr = comedi_recognize(driv, it->board_name); + if (dev->board_ptr == NULL) { + printk(KERN_WARNING + "comedi: auto config failed to find board entry" + " '%s' for driver '%s'\n", it->board_name, + driv->driver_name); + comedi_report_boards(driv); + return -EINVAL; + } + } + return driv->attach(dev, it); +} + +static int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, const int *options, + unsigned num_options) +{ + struct comedi_devconfig it; memset(&it, 0, sizeof(it)); - strncpy(it.board_name, board_name, COMEDI_NAMELEN); + strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); it.board_name[COMEDI_NAMELEN - 1] = '\0'; BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); - - mutex_lock(&dev_file_info->device->mutex); - retval = comedi_device_attach(dev_file_info->device, &it); - mutex_unlock(&dev_file_info->device->mutex); - -cleanup: - if (retval < 0) { - kfree(private_data); - comedi_free_board_minor(minor); - } - return retval; + return comedi_auto_config_helper(hardware_device, driver, + comedi_auto_config_wrapper, &it); } static void comedi_auto_unconfig(struct device *hardware_device) { - unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device); - if (minor == NULL) - return; - - BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS); + int minor; - comedi_free_board_minor(*minor); - dev_set_drvdata(hardware_device, NULL); - kfree(minor); + if (hardware_device == NULL) + return; + minor = comedi_find_board_minor(hardware_device); + if (minor < 0) + return; + BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); + comedi_free_board_minor(minor); } -int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) +static int comedi_old_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) { int options[2]; @@ -883,9 +918,30 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name) /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, board_name, + return comedi_auto_config(&pcidev->dev, driver, options, ARRAY_SIZE(options)); } + +static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev) +{ + return dev->driver->attach_pci(dev, pcidev); +} + +static int comedi_new_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&pcidev->dev, driver, + comedi_pci_attach_wrapper, pcidev); +} + +int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) +{ + + if (driver->attach_pci) + return comedi_new_pci_auto_config(pcidev, driver); + else + return comedi_old_pci_auto_config(pcidev, driver); +} EXPORT_SYMBOL_GPL(comedi_pci_auto_config); void comedi_pci_auto_unconfig(struct pci_dev *pcidev) @@ -894,16 +950,96 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev) } EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); -int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name) +int comedi_pci_driver_register(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver) +{ + int ret; + + ret = comedi_driver_register(comedi_driver); + if (ret < 0) + return ret; + + /* FIXME: Remove this test after auditing all comedi pci drivers */ + if (!pci_driver->name) + pci_driver->name = comedi_driver->driver_name; + + ret = pci_register_driver(pci_driver); + if (ret < 0) { + comedi_driver_unregister(comedi_driver); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(comedi_pci_driver_register); + +void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, + struct pci_driver *pci_driver) +{ + pci_unregister_driver(pci_driver); + comedi_driver_unregister(comedi_driver); +} +EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); + +static int comedi_old_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config(&intf->dev, driver, NULL, 0); +} + +static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) +{ + return dev->driver->attach_usb(dev, intf); +} + +static int comedi_new_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config_helper(&intf->dev, driver, + comedi_usb_attach_wrapper, intf); +} + +int comedi_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) { - BUG_ON(usbdev == NULL); - return comedi_auto_config(&usbdev->dev, board_name, NULL, 0); + BUG_ON(intf == NULL); + if (driver->attach_usb) + return comedi_new_usb_auto_config(intf, driver); + else + return comedi_old_usb_auto_config(intf, driver); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -void comedi_usb_auto_unconfig(struct usb_device *usbdev) +void comedi_usb_auto_unconfig(struct usb_interface *intf) { - BUG_ON(usbdev == NULL); - comedi_auto_unconfig(&usbdev->dev); + BUG_ON(intf == NULL); + comedi_auto_unconfig(&intf->dev); } EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); + +int comedi_usb_driver_register(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver) +{ + int ret; + + ret = comedi_driver_register(comedi_driver); + if (ret < 0) + return ret; + + ret = usb_register(usb_driver); + if (ret < 0) { + comedi_driver_unregister(comedi_driver); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(comedi_usb_driver_register); + +void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, + struct usb_driver *usb_driver) +{ + usb_deregister(usb_driver); + comedi_driver_unregister(comedi_driver); +} +EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 6c26ac8..27e39e4 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -107,31 +107,6 @@ struct subdev_8255_struct { #define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func) #define subdevpriv ((struct subdev_8255_struct *)s->private) -static int dev_8255_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dev_8255_detach(struct comedi_device *dev); -static struct comedi_driver driver_8255 = { - .driver_name = "8255", - .module = THIS_MODULE, - .attach = dev_8255_attach, - .detach = dev_8255_detach, -}; - -static int __init driver_8255_init_module(void) -{ - return comedi_driver_register(&driver_8255); -} - -static void __exit driver_8255_cleanup_module(void) -{ - comedi_driver_unregister(&driver_8255); -} - -module_init(driver_8255_init_module); -module_exit(driver_8255_cleanup_module); - -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); - void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -185,6 +160,23 @@ static int subdev_8255_insn(struct comedi_device *dev, return 2; } +static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) +{ + int config; + + config = CR_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(s->io_bits & 0x0000ff)) + config |= CR_A_IO; + if (!(s->io_bits & 0x00ff00)) + config |= CR_B_IO; + if (!(s->io_bits & 0x0f0000)) + config |= CR_C_LO_IO; + if (!(s->io_bits & 0xf00000)) + config |= CR_C_HI_IO; + CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); +} + static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -222,23 +214,6 @@ static int subdev_8255_insn_config(struct comedi_device *dev, return 1; } -static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) -{ - int config; - - config = CR_CW; - /* 1 in io_bits indicates output, 1 in config indicates input */ - if (!(s->io_bits & 0x0000ff)) - config |= CR_A_IO; - if (!(s->io_bits & 0x00ff00)) - config |= CR_B_IO; - if (!(s->io_bits & 0x0f0000)) - config |= CR_C_LO_IO; - if (!(s->io_bits & 0xf00000)) - config |= CR_C_HI_IO; - CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG); -} - static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -442,14 +417,12 @@ static int dev_8255_attach(struct comedi_device *dev, return 0; } -static int dev_8255_detach(struct comedi_device *dev) +static void dev_8255_detach(struct comedi_device *dev) { int i; unsigned long iobase; struct comedi_subdevice *s; - printk(KERN_INFO "comedi%d: 8255: remove\n", dev->minor); - for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; if (s->type != COMEDI_SUBD_UNUSED) { @@ -458,10 +431,16 @@ static int dev_8255_detach(struct comedi_device *dev) } subdev_8255_cleanup(dev, s); } - - return 0; } +static struct comedi_driver dev_8255_driver = { + .driver_name = "8255", + .module = THIS_MODULE, + .attach = dev_8255_attach, + .detach = dev_8255_detach, +}; +module_comedi_driver(dev_8255_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c index 9def225..4e4fc41 100644 --- a/drivers/staging/comedi/drivers/acl7225b.c +++ b/drivers/staging/comedi/drivers/acl7225b.c @@ -22,46 +22,13 @@ Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio) #define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */ #define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */ -static int acl7225b_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int acl7225b_detach(struct comedi_device *dev); - struct boardtype { const char *name; /* driver name */ int io_range; /* len of I/O space */ }; -static const struct boardtype boardtypes[] = { - {"acl7225b", ACL7225_SIZE,}, - {"p16r16dio", P16R16DIO_SIZE,}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) #define this_board ((const struct boardtype *)dev->board_ptr) -static struct comedi_driver driver_acl7225b = { - .driver_name = "acl7225b", - .module = THIS_MODULE, - .attach = acl7225b_attach, - .detach = acl7225b_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct boardtype), -}; - -static int __init driver_acl7225b_init_module(void) -{ - return comedi_driver_register(&driver_acl7225b); -} - -static void __exit driver_acl7225b_cleanup_module(void) -{ - comedi_driver_unregister(&driver_acl7225b); -} - -module_init(driver_acl7225b_init_module); -module_exit(driver_acl7225b_cleanup_module); - static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -152,16 +119,28 @@ static int acl7225b_attach(struct comedi_device *dev, return 0; } -static int acl7225b_detach(struct comedi_device *dev) +static void acl7225b_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: acl7225b: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, this_board->io_range); - - return 0; } +static const struct boardtype boardtypes[] = { + { "acl7225b", ACL7225_SIZE, }, + { "p16r16dio", P16R16DIO_SIZE, }, +}; + +static struct comedi_driver acl7225b_driver = { + .driver_name = "acl7225b", + .module = THIS_MODULE, + .attach = acl7225b_attach, + .detach = acl7225b_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct boardtype), +}; +module_comedi_driver(acl7225b_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index ca5bd9b8..44aaf83 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -224,2318 +224,1213 @@ MODULE_DEVICE_TABLE(pci, addi_apci_tbl); static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3120 - {"apci3120", - APCI3120_BOARD_VENDOR_ID, - 0x818D, - AMCC_OP_REG_SIZE, - APCI3120_ADDRESS_RANGE, - 8, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 16, - 8, - 16, - 8, - 0xffff, - 0x3fff, - &range_apci3120_ai, - &range_apci3120_ao, - 4, - 4, - 0x0f, - 0, - NULL, - 1, - 1, - 1, - 10000, - 100000, - v_APCI3120_Interrupt, - i_APCI3120_Reset, - i_APCI3120_InsnConfigAnalogInput, - i_APCI3120_InsnReadAnalogInput, - NULL, - NULL, - i_APCI3120_CommandTestAnalogInput, - i_APCI3120_CommandAnalogInput, - i_APCI3120_StopCyclicAcquisition, - NULL, - i_APCI3120_InsnWriteAnalogOutput, - NULL, - NULL, - i_APCI3120_InsnReadDigitalInput, - NULL, - i_APCI3120_InsnBitsDigitalInput, - i_APCI3120_InsnConfigDigitalOutput, - i_APCI3120_InsnWriteDigitalOutput, - i_APCI3120_InsnBitsDigitalOutput, - NULL, - i_APCI3120_InsnConfigTimer, - i_APCI3120_InsnWriteTimer, - i_APCI3120_InsnReadTimer, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci3120", + .i_VendorId = APCI3120_BOARD_VENDOR_ID, + .i_DeviceId = 0x818D, + .i_IorangeBase0 = AMCC_OP_REG_SIZE, + .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, + .i_IorangeBase2 = 8, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 8, + .i_AiMaxdata = 0xffff, + .i_AoMaxdata = 0x3fff, + .pr_AiRangelist = &range_apci3120_ai, + .pr_AoRangelist = &range_apci3120_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .i_Dma = 1, + .i_Timer = 1, + .b_AvailableConvertUnit = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3120_Interrupt, + .reset = i_APCI3120_Reset, + .ai_config = i_APCI3120_InsnConfigAnalogInput, + .ai_read = i_APCI3120_InsnReadAnalogInput, + .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, + .ai_cmd = i_APCI3120_CommandAnalogInput, + .ai_cancel = i_APCI3120_StopCyclicAcquisition, + .ao_write = i_APCI3120_InsnWriteAnalogOutput, + .di_read = i_APCI3120_InsnReadDigitalInput, + .di_bits = i_APCI3120_InsnBitsDigitalInput, + .do_config = i_APCI3120_InsnConfigDigitalOutput, + .do_write = i_APCI3120_InsnWriteDigitalOutput, + .do_bits = i_APCI3120_InsnBitsDigitalOutput, + .timer_config = i_APCI3120_InsnConfigTimer, + .timer_write = i_APCI3120_InsnWriteTimer, + .timer_read = i_APCI3120_InsnReadTimer, + }, #endif #ifdef CONFIG_APCI_1032 - {"apci1032", - APCI1032_BOARD_VENDOR_ID, - 0x1003, - 4, - APCI1032_ADDRESS_RANGE, - 0, - 0, - ADDIDATA_EEPROM, - ADDIDATA_93C76, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 32, - 0, - 0, - 0, - NULL, - 0, - 0, - 0, - 0, - 0, - v_APCI1032_Interrupt, - i_APCI1032_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI1032_ConfigDigitalInput, - i_APCI1032_Read1DigitalInput, - NULL, - i_APCI1032_ReadMoreDigitalInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci1032", + .i_VendorId = APCI1032_BOARD_VENDOR_ID, + .i_DeviceId = 0x1003, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .interrupt = v_APCI1032_Interrupt, + .reset = i_APCI1032_Reset, + .di_config = i_APCI1032_ConfigDigitalInput, + .di_read = i_APCI1032_Read1DigitalInput, + .di_bits = i_APCI1032_ReadMoreDigitalInput, + }, #endif #ifdef CONFIG_APCI_1516 - {"apci1516", - APCI1516_BOARD_VENDOR_ID, - 0x1001, - 128, - APCI1516_ADDRESS_RANGE, - 32, - 0, - ADDIDATA_EEPROM, - ADDIDATA_S5920, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 8, - 8, - 0, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - NULL, - i_APCI1516_Reset, - NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI1516_Read1DigitalInput, - NULL, - i_APCI1516_ReadMoreDigitalInput, - i_APCI1516_ConfigDigitalOutput, - i_APCI1516_WriteDigitalOutput, - i_APCI1516_ReadDigitalOutput, - NULL, - i_APCI1516_ConfigWatchdog, - i_APCI1516_StartStopWriteWatchdog, - i_APCI1516_ReadWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci1516", + .i_VendorId = APCI1516_BOARD_VENDOR_ID, + .i_DeviceId = 0x1001, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDiChannel = 8, + .i_NbrDoChannel = 8, + .i_Timer = 1, + .reset = i_APCI1516_Reset, + .di_read = i_APCI1516_Read1DigitalInput, + .di_bits = i_APCI1516_ReadMoreDigitalInput, + .do_config = i_APCI1516_ConfigDigitalOutput, + .do_write = i_APCI1516_WriteDigitalOutput, + .do_bits = i_APCI1516_ReadDigitalOutput, + .timer_config = i_APCI1516_ConfigWatchdog, + .timer_write = i_APCI1516_StartStopWriteWatchdog, + .timer_read = i_APCI1516_ReadWatchdog, + }, #endif #ifdef CONFIG_APCI_2016 - {"apci2016", - APCI2016_BOARD_VENDOR_ID, - 0x1002, - 128, - APCI2016_ADDRESS_RANGE, - 32, - 0, - ADDIDATA_EEPROM, - ADDIDATA_S5920, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 0, - 16, - 0, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - NULL, - i_APCI2016_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI2016_ConfigDigitalOutput, - i_APCI2016_WriteDigitalOutput, - i_APCI2016_BitsDigitalOutput, - NULL, - i_APCI2016_ConfigWatchdog, - i_APCI2016_StartStopWriteWatchdog, - i_APCI2016_ReadWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci2016", + .i_VendorId = APCI2016_BOARD_VENDOR_ID, + .i_DeviceId = 0x1002, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI2016_Reset, + .do_config = i_APCI2016_ConfigDigitalOutput, + .do_write = i_APCI2016_WriteDigitalOutput, + .do_bits = i_APCI2016_BitsDigitalOutput, + .timer_config = i_APCI2016_ConfigWatchdog, + .timer_write = i_APCI2016_StartStopWriteWatchdog, + .timer_read = i_APCI2016_ReadWatchdog, + }, #endif #ifdef CONFIG_APCI_2032 - {"apci2032", - APCI2032_BOARD_VENDOR_ID, - 0x1004, - 4, - APCI2032_ADDRESS_RANGE, - 0, - 0, - ADDIDATA_EEPROM, - ADDIDATA_93C76, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 0, - 32, - 0xffffffff, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - v_APCI2032_Interrupt, - i_APCI2032_Reset, - NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI2032_ConfigDigitalOutput, - i_APCI2032_WriteDigitalOutput, - i_APCI2032_ReadDigitalOutput, - i_APCI2032_ReadInterruptStatus, - i_APCI2032_ConfigWatchdog, - i_APCI2032_StartStopWriteWatchdog, - i_APCI2032_ReadWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci2032", + .i_VendorId = APCI2032_BOARD_VENDOR_ID, + .i_DeviceId = 0x1004, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI2032_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDoChannel = 32, + .i_DoMaxdata = 0xffffffff, + .i_Timer = 1, + .interrupt = v_APCI2032_Interrupt, + .reset = i_APCI2032_Reset, + .do_config = i_APCI2032_ConfigDigitalOutput, + .do_write = i_APCI2032_WriteDigitalOutput, + .do_bits = i_APCI2032_ReadDigitalOutput, + .do_read = i_APCI2032_ReadInterruptStatus, + .timer_config = i_APCI2032_ConfigWatchdog, + .timer_write = i_APCI2032_StartStopWriteWatchdog, + .timer_read = i_APCI2032_ReadWatchdog, + }, #endif #ifdef CONFIG_APCI_2200 - {"apci2200", - APCI2200_BOARD_VENDOR_ID, - 0x1005, - 4, - APCI2200_ADDRESS_RANGE, - 0, - 0, - ADDIDATA_EEPROM, - ADDIDATA_93C76, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 8, - 16, - 0, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - NULL, - i_APCI2200_Reset, - NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI2200_Read1DigitalInput, - NULL, - i_APCI2200_ReadMoreDigitalInput, - i_APCI2200_ConfigDigitalOutput, - i_APCI2200_WriteDigitalOutput, - i_APCI2200_ReadDigitalOutput, - NULL, - i_APCI2200_ConfigWatchdog, - i_APCI2200_StartStopWriteWatchdog, - i_APCI2200_ReadWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci2200", + .i_VendorId = APCI2200_BOARD_VENDOR_ID, + .i_DeviceId = 0x1005, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 8, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI2200_Reset, + .di_read = i_APCI2200_Read1DigitalInput, + .di_bits = i_APCI2200_ReadMoreDigitalInput, + .do_config = i_APCI2200_ConfigDigitalOutput, + .do_write = i_APCI2200_WriteDigitalOutput, + .do_bits = i_APCI2200_ReadDigitalOutput, + .timer_config = i_APCI2200_ConfigWatchdog, + .timer_write = i_APCI2200_StartStopWriteWatchdog, + .timer_read = i_APCI2200_ReadWatchdog, + }, #endif #ifdef CONFIG_APCI_1564 - {"apci1564", - APCI1564_BOARD_VENDOR_ID, - 0x1006, - 128, - APCI1564_ADDRESS_RANGE, - 0, - 0, - ADDIDATA_EEPROM, - ADDIDATA_93C76, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 32, - 32, - 0xffffffff, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - v_APCI1564_Interrupt, - i_APCI1564_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI1564_ConfigDigitalInput, - i_APCI1564_Read1DigitalInput, - NULL, - i_APCI1564_ReadMoreDigitalInput, - i_APCI1564_ConfigDigitalOutput, - i_APCI1564_WriteDigitalOutput, - i_APCI1564_ReadDigitalOutput, - i_APCI1564_ReadInterruptStatus, - i_APCI1564_ConfigTimerCounterWatchdog, - i_APCI1564_StartStopWriteTimerCounterWatchdog, - i_APCI1564_ReadTimerCounterWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci1564", + .i_VendorId = APCI1564_BOARD_VENDOR_ID, + .i_DeviceId = 0x1006, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .i_NbrDoChannel = 32, + .i_DoMaxdata = 0xffffffff, + .i_Timer = 1, + .interrupt = v_APCI1564_Interrupt, + .reset = i_APCI1564_Reset, + .di_config = i_APCI1564_ConfigDigitalInput, + .di_read = i_APCI1564_Read1DigitalInput, + .di_bits = i_APCI1564_ReadMoreDigitalInput, + .do_config = i_APCI1564_ConfigDigitalOutput, + .do_write = i_APCI1564_WriteDigitalOutput, + .do_bits = i_APCI1564_ReadDigitalOutput, + .do_read = i_APCI1564_ReadInterruptStatus, + .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, + .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI1564_ReadTimerCounterWatchdog, + }, #endif #ifdef CONFIG_APCI_1500 - {"apci1500", - APCI1500_BOARD_VENDOR_ID, - 0x80fc, - 128, - APCI1500_ADDRESS_RANGE, - 4, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 16, - 16, - 0xffff, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - v_APCI1500_Interrupt, - i_APCI1500_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI1500_ConfigDigitalInputEvent, - i_APCI1500_Initialisation, - i_APCI1500_StartStopInputEvent, - i_APCI1500_ReadMoreDigitalInput, - i_APCI1500_ConfigDigitalOutputErrorInterrupt, - i_APCI1500_WriteDigitalOutput, - i_APCI1500_ConfigureInterrupt, - NULL, - i_APCI1500_ConfigCounterTimerWatchdog, - i_APCI1500_StartStopTriggerTimerCounterWatchdog, - i_APCI1500_ReadInterruptMask, - i_APCI1500_ReadCounterTimerWatchdog, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci1500", + .i_VendorId = APCI1500_BOARD_VENDOR_ID, + .i_DeviceId = 0x80fc, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, + .i_IorangeBase2 = 4, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrDiChannel = 16, + .i_NbrDoChannel = 16, + .i_DoMaxdata = 0xffff, + .i_Timer = 1, + .interrupt = v_APCI1500_Interrupt, + .reset = i_APCI1500_Reset, + .di_config = i_APCI1500_ConfigDigitalInputEvent, + .di_read = i_APCI1500_Initialisation, + .di_write = i_APCI1500_StartStopInputEvent, + .di_bits = i_APCI1500_ReadMoreDigitalInput, + .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, + .do_write = i_APCI1500_WriteDigitalOutput, + .do_bits = i_APCI1500_ConfigureInterrupt, + .timer_config = i_APCI1500_ConfigCounterTimerWatchdog, + .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog, + .timer_read = i_APCI1500_ReadInterruptMask, + .timer_bits = i_APCI1500_ReadCounterTimerWatchdog, + }, #endif #ifdef CONFIG_APCI_3001 - {"apci3001", - APCI3120_BOARD_VENDOR_ID, - 0x828D, - AMCC_OP_REG_SIZE, - APCI3120_ADDRESS_RANGE, - 8, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 16, - 8, - 16, - 0, - 0xfff, - 0, - &range_apci3120_ai, - NULL, - 4, - 4, - 0x0f, - 0, - NULL, - 1, - 1, - 1, - 10000, - 100000, - v_APCI3120_Interrupt, - i_APCI3120_Reset, - i_APCI3120_InsnConfigAnalogInput, - i_APCI3120_InsnReadAnalogInput, - NULL, - NULL, - i_APCI3120_CommandTestAnalogInput, - i_APCI3120_CommandAnalogInput, - i_APCI3120_StopCyclicAcquisition, - NULL, - NULL, - NULL, - NULL, - i_APCI3120_InsnReadDigitalInput, - NULL, - i_APCI3120_InsnBitsDigitalInput, - i_APCI3120_InsnConfigDigitalOutput, - i_APCI3120_InsnWriteDigitalOutput, - i_APCI3120_InsnBitsDigitalOutput, - NULL, - i_APCI3120_InsnConfigTimer, - i_APCI3120_InsnWriteTimer, - i_APCI3120_InsnReadTimer, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci3001", + .i_VendorId = APCI3120_BOARD_VENDOR_ID, + .i_DeviceId = 0x828D, + .i_IorangeBase0 = AMCC_OP_REG_SIZE, + .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, + .i_IorangeBase2 = 8, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xfff, + .pr_AiRangelist = &range_apci3120_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .i_Dma = 1, + .i_Timer = 1, + .b_AvailableConvertUnit = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3120_Interrupt, + .reset = i_APCI3120_Reset, + .ai_config = i_APCI3120_InsnConfigAnalogInput, + .ai_read = i_APCI3120_InsnReadAnalogInput, + .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, + .ai_cmd = i_APCI3120_CommandAnalogInput, + .ai_cancel = i_APCI3120_StopCyclicAcquisition, + .di_read = i_APCI3120_InsnReadDigitalInput, + .di_bits = i_APCI3120_InsnBitsDigitalInput, + .do_config = i_APCI3120_InsnConfigDigitalOutput, + .do_write = i_APCI3120_InsnWriteDigitalOutput, + .do_bits = i_APCI3120_InsnBitsDigitalOutput, + .timer_config = i_APCI3120_InsnConfigTimer, + .timer_write = i_APCI3120_InsnWriteTimer, + .timer_read = i_APCI3120_InsnReadTimer, + }, #endif #ifdef CONFIG_APCI_3501 - {"apci3501", - APCI3501_BOARD_VENDOR_ID, - 0x3001, - 64, - APCI3501_ADDRESS_RANGE, - 0, - 0, - ADDIDATA_EEPROM, - ADDIDATA_S5933, - 0, - 0, - 0, - 8, - 0, - 16383, - NULL, - &range_apci3501_ao, - 2, - 2, - 0x3, - 0, - NULL, - 0, - 1, - 0, - 0, - 0, - v_APCI3501_Interrupt, - i_APCI3501_Reset, - NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3501_ConfigAnalogOutput, - i_APCI3501_WriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3501_ReadDigitalInput, - i_APCI3501_ConfigDigitalOutput, - i_APCI3501_WriteDigitalOutput, - i_APCI3501_ReadDigitalOutput, - NULL, - i_APCI3501_ConfigTimerCounterWatchdog, - i_APCI3501_StartStopWriteTimerCounterWatchdog, - i_APCI3501_ReadTimerCounterWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci3501", + .i_VendorId = APCI3501_BOARD_VENDOR_ID, + .i_DeviceId = 0x3001, + .i_IorangeBase0 = 64, + .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5933, + .i_AoMaxdata = 16383, + .pr_AoRangelist = &range_apci3501_ao, + .i_NbrDiChannel = 2, + .i_NbrDoChannel = 2, + .i_DoMaxdata = 0x3, + .i_Timer = 1, + .interrupt = v_APCI3501_Interrupt, + .reset = i_APCI3501_Reset, + .ao_config = i_APCI3501_ConfigAnalogOutput, + .ao_write = i_APCI3501_WriteAnalogOutput, + .di_bits = i_APCI3501_ReadDigitalInput, + .do_config = i_APCI3501_ConfigDigitalOutput, + .do_write = i_APCI3501_WriteDigitalOutput, + .do_bits = i_APCI3501_ReadDigitalOutput, + .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, + .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI3501_ReadTimerCounterWatchdog, + }, #endif #ifdef CONFIG_APCI_035 - {"apci035", - APCI035_BOARD_VENDOR_ID, - 0x0300, - 127, - APCI035_ADDRESS_RANGE, - 0, - 0, - 1, - ADDIDATA_S5920, - 16, - 8, - 16, - 0, - 0xff, - 0, - &range_apci035_ai, - NULL, - 0, - 0, - 0, - 0, - NULL, - 0, - 1, - 0, - 10000, - 100000, - v_APCI035_Interrupt, - i_APCI035_Reset, - i_APCI035_ConfigAnalogInput, - i_APCI035_ReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI035_ConfigTimerWatchdog, - i_APCI035_StartStopWriteTimerWatchdog, - i_APCI035_ReadTimerWatchdog, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci035", + .i_VendorId = APCI035_BOARD_VENDOR_ID, + .i_DeviceId = 0x0300, + .i_IorangeBase0 = 127, + .i_IorangeBase1 = APCI035_ADDRESS_RANGE, + .i_PCIEeprom = 1, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xff, + .pr_AiRangelist = &range_apci035_ai, + .i_Timer = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI035_Interrupt, + .reset = i_APCI035_Reset, + .ai_config = i_APCI035_ConfigAnalogInput, + .ai_read = i_APCI035_ReadAnalogInput, + .timer_config = i_APCI035_ConfigTimerWatchdog, + .timer_write = i_APCI035_StartStopWriteTimerWatchdog, + .timer_read = i_APCI035_ReadTimerWatchdog, + }, #endif #ifdef CONFIG_APCI_3200 - {"apci3200", - APCI3200_BOARD_VENDOR_ID, - 0x3000, - 128, - 256, - 4, - 4, - ADDIDATA_EEPROM, - ADDIDATA_S5920, - 16, - 8, - 16, - 0, - 0x3ffff, - 0, - &range_apci3200_ai, - NULL, - 4, - 4, - 0, - 0, - NULL, - 0, - 0, - 0, - 10000, - 100000, - v_APCI3200_Interrupt, - i_APCI3200_Reset, - i_APCI3200_ConfigAnalogInput, - i_APCI3200_ReadAnalogInput, - i_APCI3200_InsnWriteReleaseAnalogInput, - i_APCI3200_InsnBits_AnalogInput_Test, - i_APCI3200_CommandTestAnalogInput, - i_APCI3200_CommandAnalogInput, - i_APCI3200_StopCyclicAcquisition, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3200_ReadDigitalInput, - i_APCI3200_ConfigDigitalOutput, - i_APCI3200_WriteDigitalOutput, - i_APCI3200_ReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci3200", + .i_VendorId = APCI3200_BOARD_VENDOR_ID, + .i_DeviceId = 0x3000, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3200_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = i_APCI3200_ReadDigitalInput, + .do_config = i_APCI3200_ConfigDigitalOutput, + .do_write = i_APCI3200_WriteDigitalOutput, + .do_bits = i_APCI3200_ReadDigitalOutput, + }, #endif #ifdef CONFIG_APCI_3300 /* Begin JK .20.10.2004 = APCI-3300 integration */ - {"apci3300", - APCI3200_BOARD_VENDOR_ID, - 0x3007, - 128, - 256, - 4, - 4, - ADDIDATA_EEPROM, - ADDIDATA_S5920, - 0, - 8, - 8, - 0, - 0x3ffff, - 0, - &range_apci3300_ai, - NULL, - 4, - 4, - 0, - 0, - NULL, - 0, - 0, - 0, - 10000, - 100000, - v_APCI3200_Interrupt, - i_APCI3200_Reset, - i_APCI3200_ConfigAnalogInput, - i_APCI3200_ReadAnalogInput, - i_APCI3200_InsnWriteReleaseAnalogInput, - i_APCI3200_InsnBits_AnalogInput_Test, - i_APCI3200_CommandTestAnalogInput, - i_APCI3200_CommandAnalogInput, - i_APCI3200_StopCyclicAcquisition, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3200_ReadDigitalInput, - i_APCI3200_ConfigDigitalOutput, - i_APCI3200_WriteDigitalOutput, - i_APCI3200_ReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci3300", + .i_VendorId = APCI3200_BOARD_VENDOR_ID, + .i_DeviceId = 0x3007, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3300_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = i_APCI3200_ReadDigitalInput, + .do_config = i_APCI3200_ConfigDigitalOutput, + .do_write = i_APCI3200_WriteDigitalOutput, + .do_bits = i_APCI3200_ReadDigitalOutput, + }, #endif #ifdef CONFIG_APCI_1710 - {"apci1710", APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID, - 128, - 8, - 256, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 0, - 0, - 0, - 0, - NULL, - 0, - 0, - 0, - 0, - 0, - v_APCI1710_Interrupt, - i_APCI1710_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, + { + .pc_DriverName = "apci1710", + .i_VendorId = APCI1710_BOARD_VENDOR_ID, + .i_DeviceId = APCI1710_BOARD_DEVICE_ID, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 8, + .i_IorangeBase2 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .interrupt = v_APCI1710_Interrupt, + .reset = i_APCI1710_Reset, + }, #endif #ifdef CONFIG_APCI_16XX - {"apci1648", - PCI_VENDOR_ID_ADDIDATA, - 0x1009, - 128, - 0, - 0, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 0, - 0, - 0, - 48, - &range_apci16xx_ttl, - 0, - 0, - 0, - 0, - 0, - NULL, - i_APCI16XX_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI16XX_InsnConfigInitTTLIO, - i_APCI16XX_InsnBitsReadTTLIO, - i_APCI16XX_InsnReadTTLIOAllPortValue, - i_APCI16XX_InsnBitsWriteTTLIO}, - - {"apci1696", - PCI_VENDOR_ID_ADDIDATA, - 0x100A, - 128, - 0, - 0, - 0, - ADDIDATA_NO_EEPROM, - NULL, - 0, - 0, - 0, - 0, - 0, - 0, - NULL, - NULL, - 0, - 0, - 0, - 96, - &range_apci16xx_ttl, - 0, - 0, - 0, - 0, - 0, - NULL, - i_APCI16XX_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI16XX_InsnConfigInitTTLIO, - i_APCI16XX_InsnBitsReadTTLIO, - i_APCI16XX_InsnReadTTLIOAllPortValue, - i_APCI16XX_InsnBitsWriteTTLIO}, + { + .pc_DriverName = "apci1648", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1009, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 48, + .pr_TTLRangelist = &range_apci16xx_ttl, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, { + .pc_DriverName = "apci1696", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x100A, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 96, + .pr_TTLRangelist = &range_apci16xx_ttl, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, #endif #ifdef CONFIG_APCI_3XXX - {"apci3000-16", - PCI_VENDOR_ID_ADDIDATA, - 0x3010, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3000-8", - PCI_VENDOR_ID_ADDIDATA, - 0x300F, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3000-4", - PCI_VENDOR_ID_ADDIDATA, - 0x300E, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 4, - 2, - 4, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3006-16", - PCI_VENDOR_ID_ADDIDATA, - 0x3013, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3006-8", - PCI_VENDOR_ID_ADDIDATA, - 0x3014, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3006-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3015, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 4, - 2, - 4, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3010-16", - PCI_VENDOR_ID_ADDIDATA, - 0x3016, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3010-8", - PCI_VENDOR_ID_ADDIDATA, - 0x3017, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3010-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3018, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 4, - 2, - 4, - 0, - 4095, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3016-16", - PCI_VENDOR_ID_ADDIDATA, - 0x3019, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3016-8", - PCI_VENDOR_ID_ADDIDATA, - 0x301A, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3016-4", - PCI_VENDOR_ID_ADDIDATA, - 0x301B, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 4, - 2, - 4, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3100-16-4", - PCI_VENDOR_ID_ADDIDATA, - 0x301C, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 4, - 4095, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3100-8-4", - PCI_VENDOR_ID_ADDIDATA, - 0x301D, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 4, - 4095, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3106-16-4", - PCI_VENDOR_ID_ADDIDATA, - 0x301E, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 4, - 65535, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3106-8-4", - PCI_VENDOR_ID_ADDIDATA, - 0x301F, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 4, - 65535, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 10000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3110-16-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3020, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 4, - 4095, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3110-8-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3021, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 4, - 4095, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3116-16-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3022, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 16, - 8, - 16, - 4, - 65535, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3116-8-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3023, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 8, - 4, - 8, - 4, - 65535, - 4095, - &range_apci3XXX_ai, - &range_apci3XXX_ao, - 4, - 4, - 1, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, - - {"apci3003", - PCI_VENDOR_ID_ADDIDATA, - 0x300B, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 0, - 4, - 4, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 0, - NULL, - 0, - 0, - 7, - 2500, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, - - {"apci3002-16", - PCI_VENDOR_ID_ADDIDATA, - 0x3002, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 0, - 16, - 16, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 0, - NULL, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, - - {"apci3002-8", - PCI_VENDOR_ID_ADDIDATA, - 0x3003, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 0, - 8, - 8, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 0, - NULL, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, - - {"apci3002-4", - PCI_VENDOR_ID_ADDIDATA, - 0x3004, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 0, - 4, - 4, - 0, - 65535, - 0, - &range_apci3XXX_ai, - NULL, - 4, - 4, - 1, - 0, - NULL, - 0, - 0, - 6, - 5000, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - i_APCI3XXX_InsnConfigAnalogInput, - i_APCI3XXX_InsnReadAnalogInput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnReadDigitalInput, - NULL, - i_APCI3XXX_InsnBitsDigitalInput, - NULL, - i_APCI3XXX_InsnWriteDigitalOutput, - i_APCI3XXX_InsnBitsDigitalOutput, - i_APCI3XXX_InsnReadDigitalOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL}, - - {"apci3500", - PCI_VENDOR_ID_ADDIDATA, - 0x3024, - 256, - 256, - 256, - 256, - ADDIDATA_NO_EEPROM, - ADDIDATA_9054, - 0, - 0, - 0, - 4, - 0, - 4095, - NULL, - &range_apci3XXX_ao, - 0, - 0, - 0, - 24, - &range_apci3XXX_ttl, - 0, - 0, - 0, - 0, - 0, - v_APCI3XXX_Interrupt, - i_APCI3XXX_Reset, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnWriteAnalogOutput, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - i_APCI3XXX_InsnConfigInitTTLIO, - i_APCI3XXX_InsnBitsTTLIO, - i_APCI3XXX_InsnReadTTLIO, - i_APCI3XXX_InsnWriteTTLIO}, + { + .pc_DriverName = "apci3000-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3010, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3013, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3014, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3015, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3016, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3017, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3018, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3019, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301A, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301C, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301D, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3020, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3021, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3022, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3023, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3003", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 7, + .ui_MinAcquisitiontimeNs = 2500, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3002, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 16, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3003, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3004, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3500", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3024, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAoChannel = 4, + .i_AoMaxdata = 4095, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .pr_TTLRangelist = &range_apci3XXX_ttl, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, #endif }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct addi_board)) - static struct comedi_driver driver_addi = { .driver_name = ADDIDATA_DRIVER_NAME, .module = THIS_MODULE, .attach = i_ADDI_Attach, .detach = i_ADDI_Detach, - .num_names = n_boardtypes, + .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), }; @@ -2543,7 +1438,7 @@ static struct comedi_driver driver_addi = { static int __devinit driver_addi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_addi.driver_name); + return comedi_pci_auto_config(dev, &driver_addi); } static void __devexit driver_addi_pci_remove(struct pci_dev *dev) @@ -2821,16 +1716,13 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Set the initialisation flag */ devpriv->b_AiInitialisation = 1; - s->insn_config = - this_board->i_hwdrv_InsnConfigAnalogInput; - s->insn_read = this_board->i_hwdrv_InsnReadAnalogInput; - s->insn_write = - this_board->i_hwdrv_InsnWriteAnalogInput; - s->insn_bits = this_board->i_hwdrv_InsnBitsAnalogInput; - s->do_cmdtest = - this_board->i_hwdrv_CommandTestAnalogInput; - s->do_cmd = this_board->i_hwdrv_CommandAnalogInput; - s->cancel = this_board->i_hwdrv_CancelAnalogInput; + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; } else { s->type = COMEDI_SUBD_UNUSED; @@ -2846,10 +1738,8 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel; s->range_table = this_board->pr_AoRangelist; - s->insn_config = - this_board->i_hwdrv_InsnConfigAnalogOutput; - s->insn_write = - this_board->i_hwdrv_InsnWriteAnalogOutput; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2864,12 +1754,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ - s->insn_config = - this_board->i_hwdrv_InsnConfigDigitalInput; - s->insn_read = this_board->i_hwdrv_InsnReadDigitalInput; - s->insn_write = - this_board->i_hwdrv_InsnWriteDigitalInput; - s->insn_bits = this_board->i_hwdrv_InsnBitsDigitalInput; + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2886,13 +1774,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ - s->insn_config = this_board->i_hwdrv_InsnConfigDigitalOutput; /* for digital output memory.. */ - s->insn_write = - this_board->i_hwdrv_InsnWriteDigitalOutput; - s->insn_bits = - this_board->i_hwdrv_InsnBitsDigitalOutput; - s->insn_read = - this_board->i_hwdrv_InsnReadDigitalOutput; + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2907,10 +1793,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->len_chanlist = 1; s->range_table = &range_digital; - s->insn_write = this_board->i_hwdrv_InsnWriteTimer; - s->insn_read = this_board->i_hwdrv_InsnReadTimer; - s->insn_config = this_board->i_hwdrv_InsnConfigTimer; - s->insn_bits = this_board->i_hwdrv_InsnBitsTimer; + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2926,10 +1812,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) s->io_bits = 0; /* all bits input */ s->len_chanlist = this_board->i_NbrTTLChannel; s->range_table = &range_digital; - s->insn_config = this_board->i_hwdr_ConfigInitTTLIO; - s->insn_bits = this_board->i_hwdr_ReadTTLIOBits; - s->insn_read = this_board->i_hwdr_ReadTTLIOAllPortValue; - s->insn_write = this_board->i_hwdr_WriteTTLIOChlOnOff; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -2953,50 +1839,22 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -/* -+----------------------------------------------------------------------------+ -| Function name : static int i_ADDI_Detach(struct comedi_device *dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Deallocates resources of the addi_common driver | -| Free the DMA buffers, unregister irq. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_ADDI_Detach(struct comedi_device *dev) +static void i_ADDI_Detach(struct comedi_device *dev) { - if (dev->private) { - if (devpriv->b_ValidDriver) { + if (devpriv->b_ValidDriver) i_ADDI_Reset(dev); - } - - if (dev->irq) { + if (dev->irq) free_irq(dev->irq, dev); - } - - if ((this_board->pc_EepromChip == NULL) - || (strcmp(this_board->pc_EepromChip, - ADDIDATA_9054) != 0)) { - if (devpriv->allocated) { + if ((this_board->pc_EepromChip == NULL) || + (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { + if (devpriv->allocated) i_pci_card_free(devpriv->amcc); - } - if (devpriv->ul_DmaBufferVirtual[0]) { free_pages((unsigned long)devpriv-> ul_DmaBufferVirtual[0], devpriv->ui_DmaBufferPages[0]); } - if (devpriv->ul_DmaBufferVirtual[1]) { free_pages((unsigned long)devpriv-> ul_DmaBufferVirtual[1], @@ -3004,20 +1862,14 @@ static int i_ADDI_Detach(struct comedi_device *dev) } } else { iounmap(devpriv->dw_AiBase); - - if (devpriv->allocated) { + if (devpriv->allocated) i_pci_card_free(devpriv->amcc); - } } - if (pci_list_builded) { - /* v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC); */ v_pci_card_list_cleanup(this_board->i_VendorId); pci_list_builded = 0; } } - - return 0; } /* @@ -3041,7 +1893,7 @@ static int i_ADDI_Detach(struct comedi_device *dev) static int i_ADDI_Reset(struct comedi_device *dev) { - this_board->i_hwdrv_Reset(dev); + this_board->reset(dev); return 0; } @@ -3067,7 +1919,7 @@ static int i_ADDI_Reset(struct comedi_device *dev) static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; - this_board->v_hwdrv_Interrupt(irq, d); + this_board->interrupt(irq, d); return IRQ_RETVAL(1); } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index c6980b7..2c3f347 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -94,111 +94,72 @@ struct addi_board { unsigned int ui_MinDelaytimeNs; /* Minimum Delay in Nano secs */ /* interrupt and reset */ - void (*v_hwdrv_Interrupt)(int irq, void *d); - int (*i_hwdrv_Reset)(struct comedi_device *dev); + void (*interrupt)(int irq, void *d); + int (*reset)(struct comedi_device *); /* Subdevice functions */ /* ANALOG INPUT */ - int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s); - int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev, - struct comedi_subdevice *s); + int (*ai_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ai_cmdtest)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_cmd *); + int (*ai_cmd)(struct comedi_device *, struct comedi_subdevice *); + int (*ai_cancel)(struct comedi_device *, struct comedi_subdevice *); /* Analog Output */ - int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*ao_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ao_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ao_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* Digital Input */ - int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*di_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*di_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* Digital Output */ - int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + int (*do_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*do_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* TIMER */ - int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + int (*timer_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*timer_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); /* TTL IO */ - int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + int (*ttl_config)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_bits)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_read)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); + int (*ttl_write)(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *); }; /* MODULE INFO STRUCTURE */ @@ -455,7 +416,7 @@ static unsigned short pci_list_builded; /* set to 1 when list of card is known * /* Function declarations */ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int i_ADDI_Detach(struct comedi_device *dev); +static void i_ADDI_Detach(struct comedi_device *dev); static int i_ADDI_Reset(struct comedi_device *dev); static irqreturn_t v_ADDI_Interrupt(int irq, void *d); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index e886ced..ffe390c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -156,7 +156,7 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd } else us_ConvertTiming = (unsigned short) (devpriv->ui_EocEosConversionTime / 1000); /* nano to useconds */ - /* this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */ + /* this_board->ai_read(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]); */ /* Clear software registers */ devpriv->b_TimerSelectMode = 0; @@ -670,7 +670,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde /* mode 1 */ devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ - /* return this_board->i_hwdrv_CommandAnalogInput(1,dev,s); */ + /* return this_board->ai_cmd(1,dev,s); */ return i_APCI3120_CyclicAnalogInput(1, dev, s); } @@ -680,7 +680,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde /* mode 2 */ devpriv->ui_AiTimer1 = cmd->scan_begin_arg; devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ - /* return this_board->i_hwdrv_CommandAnalogInput(2,dev,s); */ + /* return this_board->ai_cmd(2,dev,s); */ return i_APCI3120_CyclicAnalogInput(2, dev, s); } return -1; @@ -1922,7 +1922,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic ui_Timervalue2 = data[1] / 1000; /* convert nano seconds to u seconds */ - /* this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(unsigned char)data[0]); */ + /* this_board->timer_config(dev, ui_Timervalue2,(unsigned char)data[0]); */ us_TmpValue = (unsigned short) inw(devpriv->iobase + APCI3120_RD_STATUS); /* @@ -2092,7 +2092,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice ui_Timervalue2 = 0; } - /* this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2); */ + /* this_board->timer_write(dev,data[0],ui_Timervalue2); */ switch (data[0]) { case APCI3120_START: @@ -2260,7 +2260,7 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice comedi_error(dev, "\nread:timer2 not configured "); } - /* this_board->i_hwdrv_InsnReadTimer(dev,data); */ + /* this_board->timer_read(dev,data); */ if (devpriv->b_Timer2Mode == APCI3120_TIMER) { /* Read the LOW unsigned short of Timer 2 register */ @@ -2331,7 +2331,7 @@ int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ - /* this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data); */ + /* this_board->di_read(dev,ui_Chan,data); */ if (ui_Chan <= 3) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); @@ -2379,7 +2379,7 @@ int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_sub *****/ *data = (ui_TmpValue >> 8) & 0xf; - /* this_board->i_hwdrv_InsnBitsDigitalInput(dev,data); */ + /* this_board->di_bits(dev,data); */ return insn->n; } @@ -2595,7 +2595,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, ui_Range = CR_RANGE(insn->chanspec); ui_Channel = CR_CHAN(insn->chanspec); - /* this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]); */ + /* this_board->ao_write(dev, ui_Range, ui_Channel,data[0]); */ if (ui_Range) { /* if 1 then unipolar */ if (data[0] != 0) diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 4fc9e85..de8c68a 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -54,8 +54,6 @@ References: #include "../comedidev.h" #include "comedi_pci.h" -#define PCI6208_DRIVER_NAME "adl_pci6208" - /* Board descriptions */ struct pci6208_board { const char *name; @@ -85,17 +83,6 @@ static const struct pci6208_board pci6208_boards[] = { } }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = { - /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ - /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci6208_pci_table); - /* Will be initialized in pci6208_find device(). */ #define thisboard ((const struct pci6208_board *)dev->board_ptr) @@ -107,157 +94,6 @@ struct pci6208_private { #define devpriv ((struct pci6208_private *)dev->private) -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci6208_detach(struct comedi_device *dev); - -static struct comedi_driver driver_pci6208 = { - .driver_name = PCI6208_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pci6208_attach, - .detach = pci6208_detach, -}; - -static int __devinit driver_pci6208_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_pci6208.driver_name); -} - -static void __devexit driver_pci6208_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_pci6208_pci_driver = { - .id_table = pci6208_pci_table, - .probe = &driver_pci6208_pci_probe, - .remove = __devexit_p(&driver_pci6208_pci_remove) -}; - -static int __init driver_pci6208_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci6208); - if (retval < 0) - return retval; - - driver_pci6208_pci_driver.name = (char *)driver_pci6208.driver_name; - return pci_register_driver(&driver_pci6208_pci_driver); -} - -static void __exit driver_pci6208_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci6208_pci_driver); - comedi_driver_unregister(&driver_pci6208); -} - -module_init(driver_pci6208_init_module); -module_exit(driver_pci6208_cleanup_module); - -static int pci6208_find_device(struct comedi_device *dev, int bus, int slot); -static int -pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, - int dev_minor); - -/*read/write functions*/ -static int pci6208_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pci6208_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* static int pci6208_dio_insn_bits (struct comedi_device *dev, - * struct comedi_subdevice *s, */ -/* struct comedi_insn *insn,unsigned int *data); */ -/* static int pci6208_dio_insn_config(struct comedi_device *dev, - * struct comedi_subdevice *s, */ -/* struct comedi_insn *insn,unsigned int *data); */ - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pci6208_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int retval; - unsigned long io_base; - - printk(KERN_INFO "comedi%d: pci6208: ", dev->minor); - - retval = alloc_private(dev, sizeof(struct pci6208_private)); - if (retval < 0) - return retval; - - retval = pci6208_find_device(dev, it->options[0], it->options[1]); - if (retval < 0) - return retval; - - retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); - if (retval < 0) - return retval; - - dev->iobase = io_base; - dev->board_name = thisboard->name; - -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 2) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; /* anything else to add here?? */ - s->n_chan = thisboard->ao_chans; - s->maxdata = 0xffff; /* 16-bit DAC */ - s->range_table = &range_bipolar10; /* this needs to be checked. */ - s->insn_write = pci6208_ao_winsn; - s->insn_read = pci6208_ao_rinsn; - - /* s=dev->subdevices+1; */ - /* digital i/o subdevice */ - /* s->type=COMEDI_SUBD_DIO; */ - /* s->subdev_flags=SDF_READABLE|SDF_WRITABLE; */ - /* s->n_chan=16; */ - /* s->maxdata=1; */ - /* s->range_table=&range_digital; */ - /* s->insn_bits = pci6208_dio_insn_bits; */ - /* s->insn_config = pci6208_dio_insn_config; */ - - printk(KERN_INFO "attached\n"); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pci6208_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pci6208: remove\n", dev->minor); - - if (devpriv && devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - - return 0; -} - static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -410,7 +246,7 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, unsigned long io_base, io_range, lcr_io_base, lcr_io_range; /* Enable PCI device and request regions */ - if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) { + if (comedi_pci_enable(pci_dev, "adl_pci6208") < 0) { printk(KERN_ERR "comedi%d: Failed to enable PCI device " "and request regions\n", dev_minor); @@ -442,6 +278,103 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr, return 0; } +static int pci6208_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int retval; + unsigned long io_base; + + printk(KERN_INFO "comedi%d: pci6208: ", dev->minor); + + retval = alloc_private(dev, sizeof(struct pci6208_private)); + if (retval < 0) + return retval; + + retval = pci6208_find_device(dev, it->options[0], it->options[1]); + if (retval < 0) + return retval; + + retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); + if (retval < 0) + return retval; + + dev->iobase = io_base; + dev->board_name = thisboard->name; + + if (alloc_subdevices(dev, 2) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; /* anything else to add here?? */ + s->n_chan = thisboard->ao_chans; + s->maxdata = 0xffff; /* 16-bit DAC */ + s->range_table = &range_bipolar10; /* this needs to be checked. */ + s->insn_write = pci6208_ao_winsn; + s->insn_read = pci6208_ao_rinsn; + + /* s=dev->subdevices+1; */ + /* digital i/o subdevice */ + /* s->type=COMEDI_SUBD_DIO; */ + /* s->subdev_flags=SDF_READABLE|SDF_WRITABLE; */ + /* s->n_chan=16; */ + /* s->maxdata=1; */ + /* s->range_table=&range_digital; */ + /* s->insn_bits = pci6208_dio_insn_bits; */ + /* s->insn_config = pci6208_dio_insn_config; */ + + printk(KERN_INFO "attached\n"); + + return 1; +} + +static void pci6208_detach(struct comedi_device *dev) +{ + if (devpriv && devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } +} + +static struct comedi_driver adl_pci6208_driver = { + .driver_name = "adl_pci6208", + .module = THIS_MODULE, + .attach = pci6208_attach, + .detach = pci6208_detach, +}; + +static int __devinit adl_pci6208_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &adl_pci6208_driver); +} + +static void __devexit adl_pci6208_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +/* This is used by modprobe to translate PCI IDs to drivers. Should + * only be used for PCI and ISA-PnP devices */ +static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { + /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ + /* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */ + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x6208) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci6208_pci_table); + +static struct pci_driver adl_pci6208_pci_driver = { + .name = "adl_pci6208", + .id_table = adl_pci6208_pci_table, + .probe = adl_pci6208_pci_probe, + .remove = __devexit_p(adl_pci6208_pci_remove), +}; +module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adl_pci7230.c b/drivers/staging/comedi/drivers/adl_pci7230.c index 20d5705..e8053bc 100644 --- a/drivers/staging/comedi/drivers/adl_pci7230.c +++ b/drivers/staging/comedi/drivers/adl_pci7230.c @@ -43,13 +43,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7230 0x7230 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); - struct adl_pci7230_private { int data; struct pci_dev *pci_dev; @@ -57,27 +50,36 @@ struct adl_pci7230_private { #define devpriv ((struct adl_pci7230_private *)dev->private) -static int adl_pci7230_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7230_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7230 = { - .driver_name = "adl_pci7230", - .module = THIS_MODULE, - .attach = adl_pci7230_attach, - .detach = adl_pci7230_detach, -}; +static int adl_pci7230_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + + outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); + } -/* Digital IO */ + return 2; +} static int adl_pci7230_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -static int adl_pci7230_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; + + return 2; +} static int adl_pci7230_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -148,89 +150,46 @@ static int adl_pci7230_attach(struct comedi_device *dev, return 1; } -static int adl_pci7230_detach(struct comedi_device *dev) +static void adl_pci7230_detach(struct comedi_device *dev) { - printk(KERN_DEBUG "comedi%d: pci7230: remove\n", dev->minor); - if (devpriv && devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - - return 0; -} - -static int adl_pci7230_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - outl((s->state << 16) & 0xffffffff, dev->iobase + PCI7230_DO); - } - - return 2; } -static int adl_pci7230_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - data[1] = inl(dev->iobase + PCI7230_DI) & 0xffffffff; - - return 2; -} +static struct comedi_driver adl_pci7230_driver = { + .driver_name = "adl_pci7230", + .module = THIS_MODULE, + .attach = adl_pci7230_attach, + .detach = adl_pci7230_detach, +}; -static int __devinit driver_adl_pci7230_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static int __devinit adl_pci7230_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7230.driver_name); + return comedi_pci_auto_config(dev, &adl_pci7230_driver); } -static void __devexit driver_adl_pci7230_pci_remove(struct pci_dev *dev) +static void __devexit adl_pci7230_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_adl_pci7230_pci_driver = { - .id_table = adl_pci7230_pci_table, - .probe = &driver_adl_pci7230_pci_probe, - .remove = __devexit_p(&driver_adl_pci7230_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adl_pci7230_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7230) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adl_pci7230_pci_table); -static int __init driver_adl_pci7230_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_adl_pci7230); - if (retval < 0) - return retval; - - driver_adl_pci7230_pci_driver.name = - (char *)driver_adl_pci7230.driver_name; - return pci_register_driver(&driver_adl_pci7230_pci_driver); -} - -static void __exit driver_adl_pci7230_cleanup_module(void) -{ - pci_unregister_driver(&driver_adl_pci7230_pci_driver); - comedi_driver_unregister(&driver_adl_pci7230); -} - -module_init(driver_adl_pci7230_init_module); -module_exit(driver_adl_pci7230_cleanup_module); +static struct pci_driver adl_pci7230_pci_driver = { + .name = "adl_pci7230", + .id_table = adl_pci7230_pci_table, + .probe = adl_pci7230_pci_probe, + .remove = __devexit_p(adl_pci7230_pci_remove), +}; +module_comedi_pci_driver(adl_pci7230_driver, adl_pci7230_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c index 9a232053..b4dae3b 100644 --- a/drivers/staging/comedi/drivers/adl_pci7296.c +++ b/drivers/staging/comedi/drivers/adl_pci7296.c @@ -48,13 +48,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7296 0x7296 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); - struct adl_pci7296_private { int data; struct pci_dev *pci_dev; @@ -63,16 +56,6 @@ struct adl_pci7296_private { #define devpriv ((struct adl_pci7296_private *)dev->private) static int adl_pci7296_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7296_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7296 = { - .driver_name = "adl_pci7296", - .module = THIS_MODULE, - .attach = adl_pci7296_attach, - .detach = adl_pci7296_detach, -}; - -static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; @@ -151,66 +134,52 @@ static int adl_pci7296_attach(struct comedi_device *dev, return -EIO; } -static int adl_pci7296_detach(struct comedi_device *dev) +static void adl_pci7296_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor); - if (devpriv && devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - /* detach four 8255 digital io subdevices */ if (dev->subdevices) { subdev_8255_cleanup(dev, dev->subdevices + 0); subdev_8255_cleanup(dev, dev->subdevices + 1); subdev_8255_cleanup(dev, dev->subdevices + 2); subdev_8255_cleanup(dev, dev->subdevices + 3); - } - - return 0; } -static int __devinit driver_adl_pci7296_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static struct comedi_driver adl_pci7296_driver = { + .driver_name = "adl_pci7296", + .module = THIS_MODULE, + .attach = adl_pci7296_attach, + .detach = adl_pci7296_detach, +}; + +static int __devinit adl_pci7296_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7296.driver_name); + return comedi_pci_auto_config(dev, &adl_pci7296_driver); } -static void __devexit driver_adl_pci7296_pci_remove(struct pci_dev *dev) +static void __devexit adl_pci7296_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_adl_pci7296_pci_driver = { - .id_table = adl_pci7296_pci_table, - .probe = &driver_adl_pci7296_pci_probe, - .remove = __devexit_p(&driver_adl_pci7296_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table); -static int __init driver_adl_pci7296_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_adl_pci7296); - if (retval < 0) - return retval; - - driver_adl_pci7296_pci_driver.name = - (char *)driver_adl_pci7296.driver_name; - return pci_register_driver(&driver_adl_pci7296_pci_driver); -} - -static void __exit driver_adl_pci7296_cleanup_module(void) -{ - pci_unregister_driver(&driver_adl_pci7296_pci_driver); - comedi_driver_unregister(&driver_adl_pci7296); -} - -module_init(driver_adl_pci7296_init_module); -module_exit(driver_adl_pci7296_cleanup_module); +static struct pci_driver adl_pci7296_pci_driver = { + .name = "adl_pci7296", + .id_table = adl_pci7296_pci_table, + .probe = adl_pci7296_pci_probe, + .remove = __devexit_p(adl_pci7296_pci_remove), +}; +module_comedi_pci_driver(adl_pci7296_driver, adl_pci7296_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c index 86ee219..9cbfb61 100644 --- a/drivers/staging/comedi/drivers/adl_pci7432.c +++ b/drivers/staging/comedi/drivers/adl_pci7432.c @@ -43,13 +43,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI7432 0x7432 -static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); - struct adl_pci7432_private { int data; struct pci_dev *pci_dev; @@ -57,29 +50,44 @@ struct adl_pci7432_private { #define devpriv ((struct adl_pci7432_private *)dev->private) -static int adl_pci7432_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci7432_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci7432 = { - .driver_name = "adl_pci7432", - .module = THIS_MODULE, - .attach = adl_pci7432_attach, - .detach = adl_pci7432_detach, -}; +static int adl_pci7432_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); + + if (insn->n != 2) + return -EINVAL; -/* Digital IO */ + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + + printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, + dev->iobase + PCI7432_DO); + outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); + } + return 2; +} static int adl_pci7432_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); + printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); -static int adl_pci7432_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + if (insn->n != 2) + return -EINVAL; + + data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; + printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); -/* */ + return 2; +} static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -153,97 +161,46 @@ static int adl_pci7432_attach(struct comedi_device *dev, return -EIO; } -static int adl_pci7432_detach(struct comedi_device *dev) +static void adl_pci7432_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pci7432: remove\n", dev->minor); - if (devpriv && devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - - return 0; } -static int adl_pci7432_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_do_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - - printk(KERN_DEBUG "comedi: out: %8x on iobase %4lx\n", s->state, - dev->iobase + PCI7432_DO); - outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO); - } - return 2; -} - -static int adl_pci7432_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - printk(KERN_DEBUG "comedi: pci7432_di_insn_bits called\n"); - printk(KERN_DEBUG "comedi: data0: %8x data1: %8x\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff; - printk(KERN_DEBUG "comedi: data1 %8x\n", data[1]); - - return 2; -} +static struct comedi_driver adl_pci7432_driver = { + .driver_name = "adl_pci7432", + .module = THIS_MODULE, + .attach = adl_pci7432_attach, + .detach = adl_pci7432_detach, +}; -static int __devinit driver_adl_pci7432_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static int __devinit adl_pci7432_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_adl_pci7432.driver_name); + return comedi_pci_auto_config(dev, &adl_pci7432_driver); } -static void __devexit driver_adl_pci7432_pci_remove(struct pci_dev *dev) +static void __devexit adl_pci7432_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_adl_pci7432_pci_driver = { - .id_table = adl_pci7432_pci_table, - .probe = &driver_adl_pci7432_pci_probe, - .remove = __devexit_p(&driver_adl_pci7432_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); -static int __init driver_adl_pci7432_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_adl_pci7432); - if (retval < 0) - return retval; - - driver_adl_pci7432_pci_driver.name = - (char *)driver_adl_pci7432.driver_name; - return pci_register_driver(&driver_adl_pci7432_pci_driver); -} - -static void __exit driver_adl_pci7432_cleanup_module(void) -{ - pci_unregister_driver(&driver_adl_pci7432_pci_driver); - comedi_driver_unregister(&driver_adl_pci7432); -} - -module_init(driver_adl_pci7432_init_module); -module_exit(driver_adl_pci7432_cleanup_module); +static struct pci_driver adl_pci7432_pci_driver = { + .name = "adl_pci7432", + .id_table = adl_pci7432_pci_table, + .probe = adl_pci7432_pci_probe, + .remove = __devexit_p(adl_pci7432_pci_remove), +}; +module_comedi_pci_driver(adl_pci7432_driver, adl_pci7432_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 3b83d65..409ef13a 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -56,13 +56,6 @@ Configuration Options: #define PCI_DEVICE_ID_PCI8164 0x8164 -static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); - struct adl_pci8164_private { int data; struct pci_dev *pci_dev; @@ -70,159 +63,6 @@ struct adl_pci8164_private { #define devpriv ((struct adl_pci8164_private *)dev->private) -static int adl_pci8164_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adl_pci8164_detach(struct comedi_device *dev); -static struct comedi_driver driver_adl_pci8164 = { - .driver_name = "adl_pci8164", - .module = THIS_MODULE, - .attach = adl_pci8164_attach, - .detach = adl_pci8164_detach, -}; - -static int adl_pci8164_insn_read_msts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_ssts(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_otp(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_buf0(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int adl_pci8164_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct pci_dev *pcidev = NULL; - struct comedi_subdevice *s; - int bus, slot; - - printk(KERN_INFO "comedi: attempt to attach...\n"); - printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); - - dev->board_name = "pci8164"; - bus = it->options[0]; - slot = it->options[1]; - - if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) - return -ENOMEM; - - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - for_each_pci_dev(pcidev) { - if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && - pcidev->device == PCI_DEVICE_ID_PCI8164) { - if (bus || slot) { - /* requested particular bus/slot */ - if (pcidev->bus->number != bus - || PCI_SLOT(pcidev->devfn) != slot) - continue; - } - devpriv->pci_dev = pcidev; - if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { - printk(KERN_ERR "comedi%d: Failed to enable " - "PCI device and request regions\n", dev->minor); - return -EIO; - } - dev->iobase = pci_resource_start(pcidev, 2); - printk(KERN_DEBUG "comedi: base addr %4lx\n", - dev->iobase); - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_msts; - s->insn_write = adl_pci8164_insn_write_cmd; - - s = dev->subdevices + 1; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_ssts; - s->insn_write = adl_pci8164_insn_write_otp; - - s = dev->subdevices + 2; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf0; - s->insn_write = adl_pci8164_insn_write_buf0; - - s = dev->subdevices + 3; - s->type = COMEDI_SUBD_PROC; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->len_chanlist = 4; - /* s->range_table = &range_axis; */ - s->insn_read = adl_pci8164_insn_read_buf1; - s->insn_write = adl_pci8164_insn_write_buf1; - - printk(KERN_INFO "comedi: attached\n"); - - return 1; - } - } - - printk(KERN_ERR "comedi%d: no supported board found!" - "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); - return -EIO; -} - -static int adl_pci8164_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pci8164: remove\n", dev->minor); - - if (devpriv && devpriv->pci_dev) { - if (dev->iobase) - comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - - return 0; -} - /* all the read commands are the same except for the addition a constant * const to the data for inw() @@ -384,45 +224,136 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } -static int __devinit driver_adl_pci8164_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static int adl_pci8164_attach(struct comedi_device *dev, + struct comedi_devconfig *it) { - return comedi_pci_auto_config(dev, driver_adl_pci8164.driver_name); + struct pci_dev *pcidev = NULL; + struct comedi_subdevice *s; + int bus, slot; + + printk(KERN_INFO "comedi: attempt to attach...\n"); + printk(KERN_INFO "comedi%d: adl_pci8164\n", dev->minor); + + dev->board_name = "pci8164"; + bus = it->options[0]; + slot = it->options[1]; + + if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + for_each_pci_dev(pcidev) { + if (pcidev->vendor == PCI_VENDOR_ID_ADLINK && + pcidev->device == PCI_DEVICE_ID_PCI8164) { + if (bus || slot) { + /* requested particular bus/slot */ + if (pcidev->bus->number != bus + || PCI_SLOT(pcidev->devfn) != slot) + continue; + } + devpriv->pci_dev = pcidev; + if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) { + printk(KERN_ERR "comedi%d: Failed to enable " + "PCI device and request regions\n", dev->minor); + return -EIO; + } + dev->iobase = pci_resource_start(pcidev, 2); + printk(KERN_DEBUG "comedi: base addr %4lx\n", + dev->iobase); + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_msts; + s->insn_write = adl_pci8164_insn_write_cmd; + + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_ssts; + s->insn_write = adl_pci8164_insn_write_otp; + + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf0; + s->insn_write = adl_pci8164_insn_write_buf0; + + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_PROC; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->len_chanlist = 4; + /* s->range_table = &range_axis; */ + s->insn_read = adl_pci8164_insn_read_buf1; + s->insn_write = adl_pci8164_insn_write_buf1; + + printk(KERN_INFO "comedi: attached\n"); + + return 1; + } + } + + printk(KERN_ERR "comedi%d: no supported board found!" + "(req. bus/slot : %d/%d)\n", dev->minor, bus, slot); + return -EIO; } -static void __devexit driver_adl_pci8164_pci_remove(struct pci_dev *dev) +static void adl_pci8164_detach(struct comedi_device *dev) { - comedi_pci_auto_unconfig(dev); + if (devpriv && devpriv->pci_dev) { + if (dev->iobase) + comedi_pci_disable(devpriv->pci_dev); + pci_dev_put(devpriv->pci_dev); + } } -static struct pci_driver driver_adl_pci8164_pci_driver = { - .id_table = adl_pci8164_pci_table, - .probe = &driver_adl_pci8164_pci_probe, - .remove = __devexit_p(&driver_adl_pci8164_pci_remove) +static struct comedi_driver adl_pci8164_driver = { + .driver_name = "adl_pci8164", + .module = THIS_MODULE, + .attach = adl_pci8164_attach, + .detach = adl_pci8164_detach, }; -static int __init driver_adl_pci8164_init_module(void) +static int __devinit adl_pci8164_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - int retval; - - retval = comedi_driver_register(&driver_adl_pci8164); - if (retval < 0) - return retval; - - driver_adl_pci8164_pci_driver.name = - (char *)driver_adl_pci8164.driver_name; - return pci_register_driver(&driver_adl_pci8164_pci_driver); + return comedi_pci_auto_config(dev, &adl_pci8164_driver); } -static void __exit driver_adl_pci8164_cleanup_module(void) +static void __devexit adl_pci8164_pci_remove(struct pci_dev *dev) { - pci_unregister_driver(&driver_adl_pci8164_pci_driver); - comedi_driver_unregister(&driver_adl_pci8164); + comedi_pci_auto_unconfig(dev); } -module_init(driver_adl_pci8164_init_module); -module_exit(driver_adl_pci8164_cleanup_module); +static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164) }, + {0} +}; +MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); + +static struct pci_driver adl_pci8164_pci_driver = { + .name = "adl_pci8164", + .id_table = adl_pci8164_pci_table, + .probe = adl_pci8164_pci_probe, + .remove = __devexit_p(adl_pci8164_pci_remove), +}; +module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 2a9bd88a..ccfb1a5 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -289,16 +289,6 @@ TODO: PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \ } while (0) -/* Function prototypes */ - -static int pci9111_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci9111_detach(struct comedi_device *dev); -static void pci9111_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *data, - unsigned int num_bytes, - unsigned int start_chan_index); - static const struct comedi_lrange pci9111_hr_ai_range = { 5, { @@ -310,14 +300,6 @@ static const struct comedi_lrange pci9111_hr_ai_range = { } }; -static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, - /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci9111_pci_table); - /* */ /* Board specification structure */ /* */ @@ -354,51 +336,6 @@ static const struct pci9111_board pci9111_boards[] = { #define pci9111_board_nbr \ (sizeof(pci9111_boards)/sizeof(struct pci9111_board)) -static struct comedi_driver pci9111_driver = { - .driver_name = PCI9111_DRIVER_NAME, - .module = THIS_MODULE, - .attach = pci9111_attach, - .detach = pci9111_detach, -}; - -static int __devinit pci9111_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, pci9111_driver.driver_name); -} - -static void __devexit pci9111_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver pci9111_driver_pci_driver = { - .id_table = pci9111_pci_table, - .probe = &pci9111_driver_pci_probe, - .remove = __devexit_p(&pci9111_driver_pci_remove) -}; - -static int __init pci9111_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&pci9111_driver); - if (retval < 0) - return retval; - - pci9111_driver_pci_driver.name = (char *)pci9111_driver.driver_name; - return pci_register_driver(&pci9111_driver_pci_driver); -} - -static void __exit pci9111_driver_cleanup_module(void) -{ - pci_unregister_driver(&pci9111_driver_pci_driver); - comedi_driver_unregister(&pci9111_driver); -} - -module_init(pci9111_driver_init_module); -module_exit(pci9111_driver_cleanup_module); - /* Private data structure */ struct pci9111_private_data { @@ -1445,31 +1382,54 @@ found: return 0; } -/* Detach */ - -static int pci9111_detach(struct comedi_device *dev) +static void pci9111_detach(struct comedi_device *dev) { - /* Reset device */ - if (dev->private != NULL) { if (dev_private->is_valid) pci9111_reset(dev); - } - /* Release previously allocated irq */ - if (dev->irq != 0) free_irq(dev->irq, dev); - if (dev_private != NULL && dev_private->pci_device != NULL) { if (dev->iobase) comedi_pci_disable(dev_private->pci_device); pci_dev_put(dev_private->pci_device); } +} - return 0; +static struct comedi_driver adl_pci9111_driver = { + .driver_name = "adl_pci9111", + .module = THIS_MODULE, + .attach = pci9111_attach, + .detach = pci9111_detach, +}; + +static int __devinit pci9111_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &adl_pci9111_driver); } +static void __devexit pci9111_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, + /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, pci9111_pci_table); + +static struct pci_driver adl_pci9111_pci_driver = { + .name = "adl_pci9111", + .id_table = pci9111_pci_table, + .probe = pci9111_pci_probe, + .remove = __devexit_p(pci9111_pci_remove), +}; +module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index f17654e..7864586 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -221,10 +221,6 @@ static const struct comedi_lrange range_pci9118hg = { 8, { * of BIP/UNI ranges */ -static int pci9118_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci9118_detach(struct comedi_device *dev); - struct boardtype { const char *name; /* board name */ int vendor_id; /* PCI vendor a device ID of card */ @@ -252,81 +248,6 @@ struct boardtype { }; -static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci9118_pci_table); - -static const struct boardtype boardtypes[] = { - {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9, - AMCC_OP_REG_SIZE, IORANGE_9118, - 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff, - &range_pci9118dg_hr, &range_bipolar10, - 3000, 12, 512}, - {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9, - AMCC_OP_REG_SIZE, IORANGE_9118, - 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff, - &range_pci9118hg, &range_bipolar10, - 3000, 12, 512}, - {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9, - AMCC_OP_REG_SIZE, IORANGE_9118, - 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff, - &range_pci9118dg_hr, &range_bipolar10, - 10000, 40, 512}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - -static struct comedi_driver driver_pci9118 = { - .driver_name = "adl_pci9118", - .module = THIS_MODULE, - .attach = pci9118_attach, - .detach = pci9118_detach, - .num_names = n_boardtypes, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), -}; - -static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_pci9118.driver_name); -} - -static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_pci9118_pci_driver = { - .id_table = pci9118_pci_table, - .probe = &driver_pci9118_pci_probe, - .remove = __devexit_p(&driver_pci9118_pci_remove) -}; - -static int __init driver_pci9118_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci9118); - if (retval < 0) - return retval; - - driver_pci9118_pci_driver.name = (char *)driver_pci9118.driver_name; - return pci_register_driver(&driver_pci9118_pci_driver); -} - -static void __exit driver_pci9118_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci9118_pci_driver); - comedi_driver_unregister(&driver_pci9118); -} - -module_init(driver_pci9118_init_module); -module_exit(driver_pci9118_cleanup_module); - struct pci9118_private { unsigned long iobase_a; /* base+size for AMCC chip */ unsigned int master; /* master capable */ @@ -2190,9 +2111,6 @@ static int pci9118_reset(struct comedi_device *dev) return 0; } -/* -============================================================================== -*/ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -2435,10 +2353,7 @@ static int pci9118_attach(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ -static int pci9118_detach(struct comedi_device *dev) +static void pci9118_detach(struct comedi_device *dev) { if (dev->private) { if (devpriv->valid) @@ -2458,13 +2373,100 @@ static int pci9118_detach(struct comedi_device *dev) free_pages((unsigned long)devpriv->dmabuf_virt[1], devpriv->dmabuf_pages[1]); } +} - return 0; +static const struct boardtype boardtypes[] = { + { + .name = "pci9118dg", + .vendor_id = PCI_VENDOR_ID_AMCC, + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hg", + .vendor_id = PCI_VENDOR_ID_AMCC, + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118hg, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hr", + .vendor_id = PCI_VENDOR_ID_AMCC, + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0xffff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 10000, + .ai_pacer_min = 40, + .half_fifo_size = 512, + }, +}; + +static struct comedi_driver adl_pci9118_driver = { + .driver_name = "adl_pci9118", + .module = THIS_MODULE, + .attach = pci9118_attach, + .detach = pci9118_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), +}; + +static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &adl_pci9118_driver); } -/* -============================================================================== -*/ +static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table); + +static struct pci_driver adl_pci9118_pci_driver = { + .name = "adl_pci9118", + .id_table = adl_pci9118_pci_table, + .probe = adl_pci9118_pci_probe, + .remove = __devexit_p(adl_pci9118_pci_remove), +}; +module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 5361f31..7d585a1 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -125,24 +125,6 @@ struct adq12b_board { int do_chans; }; -static const struct adq12b_board adq12b_boards[] = { - { - .name = "adq12b", - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 12, - .di_chans = 5, - .do_chans = 8} -/* potentially, more adq-based deviced will be added */ -/*, - .name = "adq12b", - .ai_chans = 16, // this is just for reference, hardcoded again later - .ai_bits = 12, - .di_chans = 8, - .do_chans = 5 - }*/ -}; - #define thisboard ((const struct adq12b_board *)dev->board_ptr) struct adq12b_private { @@ -156,41 +138,88 @@ struct adq12b_private { #define devpriv ((struct adq12b_private *)dev->private) /* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. + * "instructions" read/write data in "one-shot" or "software-triggered" + * mode. */ -static int adq12b_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int adq12b_detach(struct comedi_device *dev); - -static struct comedi_driver driver_adq12b = { - .driver_name = "adq12b", - .module = THIS_MODULE, - .attach = adq12b_attach, - .detach = adq12b_detach, - .board_name = &adq12b_boards[0].name, - .offset = sizeof(struct adq12b_board), - .num_names = ARRAY_SIZE(adq12b_boards), -}; static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + int n, i; + int range, channel; + unsigned char hi, lo, status; + + /* change channel and range only if it is different from the previous */ + range = CR_RANGE(insn->chanspec); + channel = CR_CHAN(insn->chanspec); + if (channel != devpriv->last_channel || range != devpriv->last_range) { + outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG); + udelay(50); /* wait for the mux to settle */ + } + + /* trigger conversion */ + status = inb(dev->iobase + ADQ12B_ADLOW); + + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + + /* wait for end of conversion */ + i = 0; + do { + /* udelay(1); */ + status = inb(dev->iobase + ADQ12B_STINR); + status = status & ADQ12B_EOC; + } while (status == 0 && ++i < TIMEOUT); + /* } while (++i < 10); */ + + /* read data */ + hi = inb(dev->iobase + ADQ12B_ADHIG); + lo = inb(dev->iobase + ADQ12B_ADLOW); + + /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", + channel, range, status, hi, lo); */ + data[n] = (hi << 8) | lo; + + } + + /* return the number of samples read/written */ + return n; +} + static int adq12b_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + + /* only bits 0-4 have information about digital inputs */ + data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f)); + + return 2; +} + static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + int channel; + + for (channel = 0; channel < 8; channel++) + if (((data[0] >> channel) & 0x01) != 0) + outb((((data[1] >> channel) & 0x01) << 3) | channel, + dev->iobase + ADQ12B_OUTBR); + + /* store information to retrieve when asked for reading */ + if (data[0]) { + devpriv->digital_state &= ~data[0]; + devpriv->digital_state |= (data[0] & data[1]); + } + + data[1] = devpriv->digital_state; + + return 2; +} -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; @@ -295,125 +324,34 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int adq12b_detach(struct comedi_device *dev) +static void adq12b_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, ADQ12B_SIZE); - kfree(devpriv); - - printk(KERN_INFO "comedi%d: adq12b: removed\n", dev->minor); - - return 0; -} - -/* - * "instructions" read/write data in "one-shot" or "software-triggered" - * mode. - */ - -static int adq12b_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data) -{ - int n, i; - int range, channel; - unsigned char hi, lo, status; - - /* change channel and range only if it is different from the previous */ - range = CR_RANGE(insn->chanspec); - channel = CR_CHAN(insn->chanspec); - if (channel != devpriv->last_channel || range != devpriv->last_range) { - outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG); - udelay(50); /* wait for the mux to settle */ - } - - /* trigger conversion */ - status = inb(dev->iobase + ADQ12B_ADLOW); - - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - - /* wait for end of conversion */ - i = 0; - do { - /* udelay(1); */ - status = inb(dev->iobase + ADQ12B_STINR); - status = status & ADQ12B_EOC; - } while (status == 0 && ++i < TIMEOUT); - /* } while (++i < 10); */ - - /* read data */ - hi = inb(dev->iobase + ADQ12B_ADHIG); - lo = inb(dev->iobase + ADQ12B_ADLOW); - - /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", - channel, range, status, hi, lo); */ - data[n] = (hi << 8) | lo; - - } - - /* return the number of samples read/written */ - return n; -} - -static int adq12b_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - /* only bits 0-4 have information about digital inputs */ - data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f)); - - return 2; } -static int adq12b_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int channel; - - for (channel = 0; channel < 8; channel++) - if (((data[0] >> channel) & 0x01) != 0) - outb((((data[1] >> channel) & 0x01) << 3) | channel, - dev->iobase + ADQ12B_OUTBR); - - /* store information to retrieve when asked for reading */ - if (data[0]) { - devpriv->digital_state &= ~data[0]; - devpriv->digital_state |= (data[0] & data[1]); - } - - data[1] = devpriv->digital_state; - - return 2; -} - -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __init driver_adq12b_init_module(void) -{ - return comedi_driver_register(&driver_adq12b); -} - -static void __exit driver_adq12b_cleanup_module(void) -{ - comedi_driver_unregister(&driver_adq12b); -} +static const struct adq12b_board adq12b_boards[] = { + { + .name = "adq12b", + .ai_se_chans = 16, + .ai_diff_chans = 8, + .ai_bits = 12, + .di_chans = 5, + .do_chans = 8, + }, +}; -module_init(driver_adq12b_init_module); -module_exit(driver_adq12b_cleanup_module); +static struct comedi_driver adq12b_driver = { + .driver_name = "adq12b", + .module = THIS_MODULE, + .attach = adq12b_attach, + .detach = adq12b_detach, + .board_name = &adq12b_boards[0].name, + .offset = sizeof(struct adq12b_board), + .num_names = ARRAY_SIZE(adq12b_boards), +}; +module_comedi_driver(adq12b_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 8318c82..de8c98c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -191,10 +191,6 @@ static const struct comedi_lrange range_pci171x_da = { 2, { } }; -static int pci1710_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci1710_detach(struct comedi_device *dev); - struct boardtype { const char *name; /* board name */ int device_id; @@ -216,17 +212,6 @@ struct boardtype { unsigned int fifo_half_size; /* size of FIFO/2 */ }; -static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci1710_pci_table); - static const struct boardtype boardtypes[] = { {"pci1710", 0x1710, IORANGE_171x, 1, TYPE_PCI171X, @@ -264,18 +249,6 @@ static const struct boardtype boardtypes[] = { {.name = DRV_NAME}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - -static struct comedi_driver driver_pci1710 = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = pci1710_attach, - .detach = pci1710_detach, - .num_names = n_boardtypes, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), -}; - struct pci1710_private { struct pci_dev *pcidev; /* ptr to PCI device */ char valid; /* card is usable */ @@ -676,7 +649,9 @@ static void interrupt_pci1710_every_sample(void *d) s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr); DPRINTK("adv_pci1710 EDBG: EOS2\n"); - if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { /* all data sampled */ + if ((!devpriv->neverending_ai) && + (devpriv->ai_act_scan >= devpriv->ai_scans)) { + /* all data sampled */ pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); @@ -804,8 +779,8 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) irq); if (!dev->attached) /* is device attached? */ return IRQ_NONE; /* no, exit */ - - if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) /* is this interrupt from our board? */ + /* is this interrupt from our board? */ + if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) return IRQ_NONE; /* no, exit */ DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n", @@ -814,7 +789,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d) if (devpriv->ai_et) { /* Switch from initial TRIG_EXT to TRIG_xxx. */ devpriv->ai_et = 0; devpriv->CntrlReg &= Control_CNT0; - devpriv->CntrlReg |= Control_SW; /* set software trigger */ + devpriv->CntrlReg |= Control_SW; /* set software trigger */ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); devpriv->CntrlReg = devpriv->ai_et_CntrlReg; outb(0, dev->iobase + PCI171x_CLRFIFO); @@ -865,7 +840,8 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev, devpriv->neverending_ai = 0; devpriv->CntrlReg &= Control_CNT0; - if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { /* don't we want wake up every scan? devpriv->ai_eos=1; */ + /* don't we want wake up every scan? devpriv->ai_eos=1; */ + if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { devpriv->ai_eos = 1; } else { devpriv->CntrlReg |= Control_ONEFH; @@ -982,13 +958,13 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(1, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", + err); return 1; } - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* step2: make sure trigger srcs are unique and mutually compatible */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) { cmd->start_src = TRIG_NOW; @@ -1015,9 +991,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(2, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", + err); return 2; } @@ -1065,9 +1041,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, #ifdef PCI171X_EXTDEBUG pci171x_cmdtest_out(3, cmd); #endif - DPRINTK - ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", - err); + DPRINTK( + "adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", + err); return 3; } @@ -1160,48 +1136,41 @@ static int check_channel_list(struct comedi_device *dev, return 0; } - if (n_chan > 1) { - chansegment[0] = chanlist[0]; /* first channel is every time ok */ - for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { /* build part of chanlist */ - /* printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ - if (chanlist[0] == chanlist[i]) - break; /* we detect loop, this must by finish */ - if (CR_CHAN(chanlist[i]) & 1) /* odd channel cann't by differencial */ - if (CR_AREF(chanlist[i]) == AREF_DIFF) { - comedi_error(dev, - "Odd channel can't be differential input!\n"); - return 0; - } - nowmustbechan = - (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; - if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) - nowmustbechan = (nowmustbechan + 1) % s->n_chan; - if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk - ("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); - return 0; - } - chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */ + if (n_chan == 1) + return 1; /* seglen=1 */ + + chansegment[0] = chanlist[0]; /* first channel is every time ok */ + for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { + if (chanlist[0] == chanlist[i]) + break; /* we detected a loop, stop */ + if ((CR_CHAN(chanlist[i]) & 1) && + (CR_AREF(chanlist[i]) == AREF_DIFF)) { + comedi_error(dev, "Odd channel cannot be differential input!\n"); + return 0; } + nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; + if (CR_AREF(chansegment[i - 1]) == AREF_DIFF) + nowmustbechan = (nowmustbechan + 1) % s->n_chan; + if (nowmustbechan != CR_CHAN(chanlist[i])) { + printk("channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); + return 0; + } + chansegment[i] = chanlist[i]; /* next correct channel in list */ + } - for (i = 0, segpos = 0; i < n_chan; i++) { /* check whole chanlist */ - /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */ - if (chanlist[i] != chansegment[i % seglen]) { - printk - ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); - return 0; /* chan/gain list is strange */ - } + for (i = 0, segpos = 0; i < n_chan; i++) { + if (chanlist[i] != chansegment[i % seglen]) { + printk("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); + return 0; } - } else { - seglen = 1; } return seglen; } @@ -1221,14 +1190,14 @@ static void setup_channel_list(struct comedi_device *dev, DPRINTK("SegLen: %d\n", seglen); for (i = 0; i < seglen; i++) { /* store range list to card */ chanprog = muxonechan[CR_CHAN(chanlist[i])]; - outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ + outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */ range = this_board->rangecode_ai[CR_RANGE(chanlist[i])]; if (CR_AREF(chanlist[i]) == AREF_DIFF) range |= 0x0020; - outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ + outw(range, dev->iobase + PCI171x_RANGE); /* select gain */ #ifdef PCI171x_PARANOIDCHECK devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; + (CR_CHAN(chanlist[i]) << 12) & 0xf000; #endif DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, devpriv->act_chanlist[i]); @@ -1236,13 +1205,14 @@ static void setup_channel_list(struct comedi_device *dev, #ifdef PCI171x_PARANOIDCHECK for ( ; i < n_chan; i++) { /* store remainder of channel list */ devpriv->act_chanlist[i] = - (CR_CHAN(chanlist[i]) << 12) & 0xf000; + (CR_CHAN(chanlist[i]) << 12) & 0xf000; } #endif devpriv->ai_et_MuxVal = - CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); - outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); /* select channel interval to scan */ + CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8); + /* select channel interval to scan */ + outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); DPRINTK("MUX: %4x L%4x.H%4x\n", CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8), CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1])); @@ -1365,9 +1335,6 @@ static int pci1710_reset(struct comedi_device *dev) DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n"); } -/* -============================================================================== -*/ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1398,13 +1365,13 @@ static int pci1710_attach(struct comedi_device *dev, while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH, PCI_ANY_ID, pcidev))) { if (strcmp(this_board->name, DRV_NAME) == 0) { - for (i = 0; i < n_boardtypes; ++i) { + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { if (pcidev->device == boardtypes[i].device_id) { board_index = i; break; } } - if (i == n_boardtypes) + if (i == ARRAY_SIZE(boardtypes)) continue; } else { if (pcidev->device != boardtypes[board_index].device_id) @@ -1584,12 +1551,8 @@ static int pci1710_attach(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ -static int pci1710_detach(struct comedi_device *dev) +static void pci1710_detach(struct comedi_device *dev) { - if (dev->private) { if (devpriv->valid) pci1710_reset(dev); @@ -1598,57 +1561,49 @@ static int pci1710_detach(struct comedi_device *dev) if (devpriv->pcidev) { if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - pci_dev_put(devpriv->pcidev); } } - - return 0; } -/* -============================================================================== -*/ -static int __devinit driver_pci1710_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver adv_pci1710_driver = { + .driver_name = "adv_pci1710", + .module = THIS_MODULE, + .attach = pci1710_attach, + .detach = pci1710_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), +}; + +static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci1710.driver_name); + return comedi_pci_auto_config(dev, &adv_pci1710_driver); } -static void __devexit driver_pci1710_pci_remove(struct pci_dev *dev) +static void __devexit adv_pci1710_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_pci1710_pci_driver = { - .id_table = pci1710_pci_table, - .probe = &driver_pci1710_pci_probe, - .remove = __devexit_p(&driver_pci1710_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1710) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1711) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1713) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1720) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1731) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adv_pci1710_pci_table); -static int __init driver_pci1710_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci1710); - if (retval < 0) - return retval; - - driver_pci1710_pci_driver.name = (char *)driver_pci1710.driver_name; - return pci_register_driver(&driver_pci1710_pci_driver); -} - -static void __exit driver_pci1710_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci1710_pci_driver); - comedi_driver_unregister(&driver_pci1710); -} - -module_init(driver_pci1710_init_module); -module_exit(driver_pci1710_cleanup_module); -/* -============================================================================== -*/ +static struct pci_driver adv_pci1710_pci_driver = { + .name = "adv_pci1710", + .id_table = adv_pci1710_pci_table, + .probe = adv_pci1710_pci_probe, + .remove = __devexit_p(adv_pci1710_pci_remove), +}; +module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 29455a8..336addc 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -150,36 +150,6 @@ static const struct pci1723_board boardtypes[] = { }, }; -/* - * This is used by modprobe to translate PCI IDs to drivers. - * Should only be used for PCI and ISA-PnP devices - */ -static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci1723_pci_table); - -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pci1723_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci1723_detach(struct comedi_device *dev); - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board)) - -static struct comedi_driver driver_pci1723 = { - .driver_name = "adv_pci1723", - .module = THIS_MODULE, - .attach = pci1723_attach, - .detach = pci1723_detach, -}; - /* This structure is for data unique to this hardware driver. */ struct pci1723_private { int valid; /* card is usable; */ @@ -319,10 +289,6 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return 2; } -/* - * Attach is called by the Comedi core to configure the driver - * for a pci1723 board. - */ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -465,73 +431,50 @@ static int pci1723_attach(struct comedi_device *dev, return 0; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pci1723_detach(struct comedi_device *dev) +static void pci1723_detach(struct comedi_device *dev) { - printk(KERN_ERR "comedi%d: pci1723: remove\n", dev->minor); - if (dev->private) { if (devpriv->valid) pci1723_reset(dev); - if (devpriv->pcidev) { if (dev->iobase) comedi_pci_disable(devpriv->pcidev); pci_dev_put(devpriv->pcidev); } } - - return 0; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit driver_pci1723_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver adv_pci1723_driver = { + .driver_name = "adv_pci1723", + .module = THIS_MODULE, + .attach = pci1723_attach, + .detach = pci1723_detach, +}; + +static int __devinit adv_pci1723_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci1723.driver_name); + return comedi_pci_auto_config(dev, &adv_pci1723_driver); } -static void __devexit driver_pci1723_pci_remove(struct pci_dev *dev) +static void __devexit adv_pci1723_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_pci1723_pci_driver = { - .id_table = pci1723_pci_table, - .probe = &driver_pci1723_pci_probe, - .remove = __devexit_p(&driver_pci1723_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adv_pci1723_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adv_pci1723_pci_table); -static int __init driver_pci1723_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci1723); - if (retval < 0) - return retval; - - driver_pci1723_pci_driver.name = (char *)driver_pci1723.driver_name; - return pci_register_driver(&driver_pci1723_pci_driver); -} - -static void __exit driver_pci1723_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci1723_pci_driver); - comedi_driver_unregister(&driver_pci1723); -} - -module_init(driver_pci1723_init_module); -module_exit(driver_pci1723_cleanup_module); +static struct pci_driver adv_pci1723_pci_driver = { + .name = "adv_pci1723", + .id_table = adv_pci1723_pci_table, + .probe = adv_pci1723_pci_probe, + .remove = __devexit_p(adv_pci1723_pci_remove), +}; +module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 7af068f..43a32dc 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -237,10 +237,6 @@ enum hw_io_access { #define OMBCMD_RETRY 0x03 /* 3 times try request before error */ -static int pci_dio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci_dio_detach(struct comedi_device *dev); - struct diosubd_data { int chans; /* num of chans */ int addr; /* PCI address ofset */ @@ -263,26 +259,6 @@ struct dio_boardtype { enum hw_io_access io_access; }; -static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1730) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1733) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1753) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1754) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1756) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1762) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pci_dio_pci_table); - static const struct dio_boardtype boardtypes[] = { {"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG, TYPE_PCI1730, @@ -406,15 +382,6 @@ static const struct dio_boardtype boardtypes[] = { IO_16b} }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype)) - -static struct comedi_driver driver_pci_dio = { - .driver_name = "adv_pci_dio", - .module = THIS_MODULE, - .attach = pci_dio_attach, - .detach = pci_dio_detach -}; - struct pci_dio_private { struct pci_dio_private *prev; /* previous private struct */ struct pci_dio_private *next; /* next private struct */ @@ -1116,9 +1083,6 @@ static int CheckAndAllocCard(struct comedi_device *dev, return 1; } -/* -============================================================================== -*/ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1134,7 +1098,7 @@ static int pci_dio_attach(struct comedi_device *dev, for_each_pci_dev(pcidev) { /* loop through cards supported by this driver */ - for (i = 0; i < n_boardtypes; ++i) { + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { if (boardtypes[i].vendor_id != pcidev->vendor) continue; if (boardtypes[i].device_id != pcidev->device) @@ -1162,7 +1126,7 @@ static int pci_dio_attach(struct comedi_device *dev, return -EIO; } - if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) { + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { dev_err(dev->hw_dev, "Error: Can't enable PCI device and request regions!\n"); return -EIO; } @@ -1246,10 +1210,7 @@ static int pci_dio_attach(struct comedi_device *dev, return 0; } -/* -============================================================================== -*/ -static int pci_dio_detach(struct comedi_device *dev) +static void pci_dio_detach(struct comedi_device *dev) { int i, j; struct comedi_subdevice *s; @@ -1258,20 +1219,14 @@ static int pci_dio_detach(struct comedi_device *dev) if (dev->private) { if (devpriv->valid) pci_dio_reset(dev); - - - /* This shows the silliness of using this kind of - * scheme for numbering subdevices. Don't do it. --ds */ subdev = 0; for (i = 0; i < MAX_DI_SUBDEVS; i++) { if (this_board->sdi[i].chans) subdev++; - } for (i = 0; i < MAX_DO_SUBDEVS; i++) { if (this_board->sdo[i].chans) subdev++; - } for (i = 0; i < MAX_DIO_SUBDEVG; i++) { for (j = 0; j < this_board->sdio[i].regs; j++) { @@ -1280,82 +1235,73 @@ static int pci_dio_detach(struct comedi_device *dev) subdev++; } } - if (this_board->boardid.chans) subdev++; - for (i = 0; i < MAX_8254_SUBDEVS; i++) if (this_board->s8254[i].chans) subdev++; - for (i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; s->private = NULL; } - if (devpriv->pcidev) { if (dev->iobase) comedi_pci_disable(devpriv->pcidev); - pci_dev_put(devpriv->pcidev); } - if (devpriv->prev) devpriv->prev->next = devpriv->next; else pci_priv = devpriv->next; - if (devpriv->next) devpriv->next->prev = devpriv->prev; - } - - return 0; } -/* -============================================================================== -*/ -static int __devinit driver_pci_dio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver adv_pci_dio_driver = { + .driver_name = "adv_pci_dio", + .module = THIS_MODULE, + .attach = pci_dio_attach, + .detach = pci_dio_detach +}; + +static int __devinit adv_pci_dio_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pci_dio.driver_name); + return comedi_pci_auto_config(dev, &adv_pci_dio_driver); } -static void __devexit driver_pci_dio_pci_remove(struct pci_dev *dev) +static void __devexit adv_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_pci_dio_pci_driver = { - .id_table = pci_dio_pci_table, - .probe = &driver_pci_dio_pci_probe, - .remove = __devexit_p(&driver_pci_dio_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1730) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1733) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1753) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1754) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1756) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1760) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1762) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, adv_pci_dio_pci_table); -static int __init driver_pci_dio_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pci_dio); - if (retval < 0) - return retval; - - driver_pci_dio_pci_driver.name = (char *)driver_pci_dio.driver_name; - return pci_register_driver(&driver_pci_dio_pci_driver); -} - -static void __exit driver_pci_dio_cleanup_module(void) -{ - pci_unregister_driver(&driver_pci_dio_pci_driver); - comedi_driver_unregister(&driver_pci_dio); -} - -module_init(driver_pci_dio_init_module); -module_exit(driver_pci_dio_cleanup_module); -/* -============================================================================== -*/ +static struct pci_driver adv_pci_dio_pci_driver = { + .name = "adv_pci_dio", + .id_table = adv_pci_dio_pci_table, + .probe = adv_pci_dio_pci_probe, + .remove = __devexit_p(adv_pci_dio_pci_remove), +}; +module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index b0f98e5..64d82bc 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -209,36 +209,23 @@ static int aio_aio12_8_attach(struct comedi_device *dev, return 0; } -static int aio_aio12_8_detach(struct comedi_device *dev) +static void aio_aio12_8_detach(struct comedi_device *dev) { subdev_8255_cleanup(dev, &dev->subdevices[2]); if (dev->iobase) release_region(dev->iobase, 24); - return 0; } -static struct comedi_driver driver_aio_aio12_8 = { - .driver_name = "aio_aio12_8", - .module = THIS_MODULE, - .attach = aio_aio12_8_attach, - .detach = aio_aio12_8_detach, - .board_name = &board_types[0].name, - .num_names = 1, - .offset = sizeof(struct aio12_8_boardtype), +static struct comedi_driver aio_aio12_8_driver = { + .driver_name = "aio_aio12_8", + .module = THIS_MODULE, + .attach = aio_aio12_8_attach, + .detach = aio_aio12_8_detach, + .board_name = &board_types[0].name, + .num_names = ARRAY_SIZE(board_types), + .offset = sizeof(struct aio12_8_boardtype), }; - -static int __init driver_aio_aio12_8_init_module(void) -{ - return comedi_driver_register(&driver_aio_aio12_8); -} - -static void __exit driver_aio_aio12_8_cleanup_module(void) -{ - comedi_driver_unregister(&driver_aio_aio12_8); -} - -module_init(driver_aio_aio12_8_init_module); -module_exit(driver_aio_aio12_8_cleanup_module); +module_comedi_driver(aio_aio12_8_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 160b0a0..04f6f94 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -67,30 +67,41 @@ struct aio_iiro_16_private { #define devpriv ((struct aio_iiro_16_private *) dev->private) -static int aio_iiro_16_attach(struct comedi_device *dev, - struct comedi_devconfig *it); - -static int aio_iiro_16_detach(struct comedi_device *dev); - -static struct comedi_driver driver_aio_iiro_16 = { - .driver_name = "aio_iiro_16", - .module = THIS_MODULE, - .attach = aio_iiro_16_attach, - .detach = aio_iiro_16_detach, - .board_name = &aio_iiro_16_boards[0].name, - .offset = sizeof(struct aio_iiro_16_board), - .num_names = ARRAY_SIZE(aio_iiro_16_boards), -}; +static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); + outb((s->state >> 8) & 0xff, + dev->iobase + AIO_IIRO_16_RELAY_8_15); + } + + data[1] = s->state; + + return 2; +} static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); + unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; -static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); + data[1] = 0; + data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); + data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; + + return 2; +} static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -138,64 +149,22 @@ static int aio_iiro_16_attach(struct comedi_device *dev, return 1; } -static int aio_iiro_16_detach(struct comedi_device *dev) +static void aio_iiro_16_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: aio_iiro_16: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, AIO_IIRO_16_SIZE); - - return 0; -} - -static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7); - outb((s->state >> 8) & 0xff, - dev->iobase + AIO_IIRO_16_RELAY_8_15); - } - - data[1] = s->state; - - return 2; -} - -static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - data[1] = 0; - data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7); - data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8; - - return 2; -} - -static int __init driver_aio_iiro_16_init_module(void) -{ - return comedi_driver_register(&driver_aio_iiro_16); } -static void __exit driver_aio_iiro_16_cleanup_module(void) -{ - comedi_driver_unregister(&driver_aio_iiro_16); -} - -module_init(driver_aio_iiro_16_init_module); -module_exit(driver_aio_iiro_16_cleanup_module); +static struct comedi_driver aio_iiro_16_driver = { + .driver_name = "aio_iiro_16", + .module = THIS_MODULE, + .attach = aio_iiro_16_attach, + .detach = aio_iiro_16_detach, + .board_name = &aio_iiro_16_boards[0].name, + .offset = sizeof(struct aio_iiro_16_board), + .num_names = ARRAY_SIZE(aio_iiro_16_boards), +}; +module_comedi_driver(aio_iiro_16_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 566cc44..c9c5d97 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -217,6 +217,14 @@ order they appear in the channel list. #define DIO200_DRIVER_NAME "amplc_dio200" +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_DIO200_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_DIO200_PCI +#endif + /* PCI IDs */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a @@ -274,10 +282,14 @@ enum dio200_model { }; enum dio200_layout { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA pc212_layout, pc214_layout, +#endif pc215_layout, +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA pc218_layout, +#endif pc272_layout }; @@ -290,6 +302,7 @@ struct dio200_board { }; static const struct dio200_board dio200_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA { .name = "pc212e", .bustype = isa_bustype, @@ -308,15 +321,6 @@ static const struct dio200_board dio200_boards[] = { .model = pc215e_model, .layout = pc215_layout, }, -#ifdef CONFIG_COMEDI_PCI - { - .name = "pci215", - .devid = PCI_DEVICE_ID_AMPLICON_PCI215, - .bustype = pci_bustype, - .model = pci215_model, - .layout = pc215_layout, - }, -#endif { .name = "pc218e", .bustype = isa_bustype, @@ -329,7 +333,15 @@ static const struct dio200_board dio200_boards[] = { .model = pc272e_model, .layout = pc272_layout, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI + { + .name = "pci215", + .devid = PCI_DEVICE_ID_AMPLICON_PCI215, + .bustype = pci_bustype, + .model = pci215_model, + .layout = pc215_layout, + }, { .name = "pci272", .devid = PCI_DEVICE_ID_AMPLICON_PCI272, @@ -337,8 +349,6 @@ static const struct dio200_board dio200_boards[] = { .model = pci272_model, .layout = pc272_layout, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = DIO200_DRIVER_NAME, .devid = PCI_DEVICE_ID_INVALID, @@ -367,6 +377,7 @@ struct dio200_layout_struct { }; static const struct dio200_layout_struct dio200_layouts[] = { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA [pc212_layout] = { .n_subdevs = 6, .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, @@ -385,6 +396,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 0, .has_clk_gat_sce = 0, }, +#endif [pc215_layout] = { .n_subdevs = 5, .sdtype = {sd_8255, sd_8255, sd_8254, @@ -394,6 +406,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA [pc218_layout] = { .n_subdevs = 7, .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, @@ -405,6 +418,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 1, }, +#endif [pc272_layout] = { .n_subdevs = 4, .sdtype = {sd_8255, sd_8255, sd_8255, @@ -419,7 +433,7 @@ static const struct dio200_layout_struct dio200_layouts[] = { * PCI driver table. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, @@ -427,7 +441,7 @@ static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { }; MODULE_DEVICE_TABLE(pci, dio200_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_DIO200_PCI */ /* * Useful for shorthand access to the particular board structure @@ -441,7 +455,7 @@ MODULE_DEVICE_TABLE(pci, dio200_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct dio200_private { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI struct pci_dev *pci_dev; /* PCI device */ #endif int intr_sd; @@ -479,7 +493,7 @@ struct dio200_subdev_intr { */ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dio200_detach(struct comedi_device *dev); +static void dio200_detach(struct comedi_device *dev); static struct comedi_driver driver_amplc_dio200 = { .driver_name = DIO200_DRIVER_NAME, .module = THIS_MODULE, @@ -490,12 +504,12 @@ static struct comedi_driver driver_amplc_dio200 = { .num_names = ARRAY_SIZE(dio200_boards), }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_dio200); } static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev) @@ -549,7 +563,7 @@ module_exit(driver_amplc_dio200_cleanup_module); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI static int dio200_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -611,6 +625,7 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot, * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA static int dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -621,6 +636,7 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) } return 0; } +#endif /* * 'insn_bits' function for an 'INTERRUPT' subdevice. @@ -1332,7 +1348,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -1354,12 +1370,14 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA case isa_bustype: iobase = it->options[0]; irq = it->options[1]; share_irq = 0; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -1382,7 +1400,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->intr_sd = -1; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { @@ -1396,9 +1414,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -1474,12 +1494,19 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI + case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); @@ -1491,22 +1518,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int dio200_detach(struct comedi_device *dev) +static void dio200_detach(struct comedi_device *dev) { const struct dio200_layout_struct *layout; unsigned n; - printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, - DIO200_DRIVER_NAME); - if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { @@ -1529,7 +1545,7 @@ static int dio200_detach(struct comedi_device *dev) } } if (devpriv) { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_DIO200_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -1537,15 +1553,12 @@ static int dio200_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_DIO200_ISA if (dev->iobase) release_region(dev->iobase, DIO200_IO_SIZE); +#endif } } - if (dev->board_name) - printk(KERN_INFO "comedi%d: %s removed\n", - dev->minor, dev->board_name); - - return 0; } MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 7972cad..57ba322 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -63,6 +63,14 @@ unused. #define PC236_DRIVER_NAME "amplc_pc236" +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_PC236_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_PC236_PCI +#endif + /* PCI236 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 @@ -106,13 +114,15 @@ struct pc236_board { enum pc236_model model; }; static const struct pc236_board pc236_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA { .name = "pc36at", .fancy_name = "PC36AT", .bustype = isa_bustype, .model = pc36at_model, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI { .name = "pci236", .fancy_name = "PCI236", @@ -120,8 +130,6 @@ static const struct pc236_board pc236_boards[] = { .bustype = pci_bustype, .model = pci236_model, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = PC236_DRIVER_NAME, .fancy_name = PC236_DRIVER_NAME, @@ -132,14 +140,14 @@ static const struct pc236_board pc236_boards[] = { #endif }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} }; MODULE_DEVICE_TABLE(pci, pc236_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC236_PCI */ /* * Useful for shorthand access to the particular board structure @@ -151,7 +159,7 @@ MODULE_DEVICE_TABLE(pci, pc236_pci_table); feel free to suggest moving the variable to the struct comedi_device struct. */ struct pc236_private { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI /* PCI device */ struct pci_dev *pci_dev; unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */ @@ -168,7 +176,7 @@ struct pc236_private { * the device code. */ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int pc236_detach(struct comedi_device *dev); +static void pc236_detach(struct comedi_device *dev); static struct comedi_driver driver_amplc_pc236 = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, @@ -179,12 +187,12 @@ static struct comedi_driver driver_amplc_pc236 = { .num_names = ARRAY_SIZE(pc236_boards), }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static int __devinit driver_amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pc236.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pc236); } static void __devexit driver_amplc_pc236_pci_remove(struct pci_dev *dev) @@ -234,8 +242,10 @@ module_init(driver_amplc_pc236_init_module); module_exit(driver_amplc_pc236_cleanup_module); #endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent); +#endif static void pc236_intr_disable(struct comedi_device *dev); static void pc236_intr_enable(struct comedi_device *dev); static int pc236_intr_check(struct comedi_device *dev); @@ -255,7 +265,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d); * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI static int pc236_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -324,7 +334,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; unsigned long iobase = 0; unsigned int irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -345,12 +355,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA case isa_bustype: iobase = it->options[0]; irq = it->options[1]; share_irq = 0; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -361,7 +373,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; devpriv->pci_dev = pci_dev; break; -#endif /* CONFIG_COMEDI_PCI */ +#endif default: printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n", @@ -376,7 +388,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME); @@ -392,9 +404,11 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -439,12 +453,19 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI + case pci_bustype: printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } if (irq) printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); @@ -456,27 +477,16 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pc236_detach(struct comedi_device *dev) +static void pc236_detach(struct comedi_device *dev) { - printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, - PC236_DRIVER_NAME); if (devpriv) pc236_intr_disable(dev); - if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); if (devpriv) { -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -484,21 +494,19 @@ static int pc236_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA if (dev->iobase) release_region(dev->iobase, PC236_IO_SIZE); +#endif } } - if (dev->board_name) { - printk(KERN_INFO "comedi%d: %s removed\n", - dev->minor, dev->board_name); - } - return 0; } /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_PC236_ISA static int pc236_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -509,6 +517,7 @@ static int pc236_request_region(unsigned minor, unsigned long from, } return 0; } +#endif /* * This function is called to mark the interrupt as disabled (no command @@ -521,7 +530,7 @@ static void pc236_intr_disable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -539,7 +548,7 @@ static void pc236_intr_enable(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->enable_irq = 1; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR); #endif @@ -561,7 +570,7 @@ static int pc236_intr_check(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->enable_irq) { retval = 1; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC236_PCI if (devpriv->lcr_iobase) { if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR) & PLX9052_INTCSR_LI1STAT_MASK) diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 191ac0d..974d745 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -50,6 +50,14 @@ The state of the outputs can be read. #define PC263_DRIVER_NAME "amplc_pc263" +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA_MODULE +#define CONFIG_COMEDI_AMPLC_PC263_ISA +#endif + +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI_MODULE +#define CONFIG_COMEDI_AMPLC_PC263_PCI +#endif + /* PCI263 PCI configuration register information */ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c @@ -73,13 +81,15 @@ struct pc263_board { enum pc263_model model; }; static const struct pc263_board pc263_boards[] = { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA { .name = "pc263", .fancy_name = "PC263", .bustype = isa_bustype, .model = pc263_model, }, -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI { .name = "pci263", .fancy_name = "PCI263", @@ -87,8 +97,6 @@ static const struct pc263_board pc263_boards[] = { .bustype = pci_bustype, .model = pci263_model, }, -#endif -#ifdef CONFIG_COMEDI_PCI { .name = PC263_DRIVER_NAME, .fancy_name = PC263_DRIVER_NAME, @@ -99,14 +107,14 @@ static const struct pc263_board pc263_boards[] = { #endif }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} }; MODULE_DEVICE_TABLE(pci, pc263_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ /* * Useful for shorthand access to the particular board structure @@ -117,14 +125,14 @@ MODULE_DEVICE_TABLE(pci, pc263_pci_table); several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI struct pc263_private { /* PCI device. */ struct pci_dev *pci_dev; }; #define devpriv ((struct pc263_private *)dev->private) -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_AMPLC_PC263_PCI */ /* * The struct comedi_driver structure tells the Comedi core module @@ -133,7 +141,7 @@ struct pc263_private { * the device code. */ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int pc263_detach(struct comedi_device *dev); +static void pc263_detach(struct comedi_device *dev); static struct comedi_driver driver_amplc_pc263 = { .driver_name = PC263_DRIVER_NAME, .module = THIS_MODULE, @@ -144,8 +152,10 @@ static struct comedi_driver driver_amplc_pc263 = { .num_names = ARRAY_SIZE(pc263_boards), }; +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent); +#endif static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -157,7 +167,7 @@ static int pc263_dio_insn_config(struct comedi_device *dev, * This function looks for a PCI device matching the requested board name, * bus and slot. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static int pc263_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) @@ -225,7 +235,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; unsigned long iobase = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI struct pci_dev *pci_dev = NULL; int bus = 0, slot = 0; #endif @@ -237,7 +247,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) * Allocate the private structure area. alloc_private() is a * convenient macro defined in comedidev.h. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI ret = alloc_private(dev, sizeof(struct pc263_private)); if (ret < 0) { printk(KERN_ERR "comedi%d: error! out of memory!\n", @@ -247,10 +257,12 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif /* Process options. */ switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA case isa_bustype: iobase = it->options[0]; break; -#ifdef CONFIG_COMEDI_PCI +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI case pci_bustype: bus = it->options[0]; slot = it->options[1]; @@ -260,7 +272,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; devpriv->pci_dev = pci_dev; break; -#endif /* CONFIG_COMEDI_PCI */ +#endif default: printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n", @@ -275,7 +287,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Enable device and reserve I/O spaces. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI if (pci_dev) { ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME); if (ret < 0) { @@ -289,9 +301,11 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE); if (ret < 0) return ret; +#endif } dev->iobase = iobase; @@ -322,12 +336,18 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->state = s->state | (inb(dev->iobase) << 8); printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); - if (thisboard->bustype == isa_bustype) { + switch (thisboard->bustype) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA + case isa_bustype: printk("(base %#lx) ", iobase); - } else { -#ifdef CONFIG_COMEDI_PCI + break; +#endif +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI printk("(pci %s) ", pci_name(pci_dev)); + break; #endif + default: + break; } printk("attached\n"); @@ -335,23 +355,13 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pc263_detach(struct comedi_device *dev) +static void pc263_detach(struct comedi_device *dev) { - printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, - PC263_DRIVER_NAME); - -#ifdef CONFIG_COMEDI_PCI - if (devpriv) { +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI + if (devpriv) #endif -#ifdef CONFIG_COMEDI_PCI + { +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); @@ -359,21 +369,19 @@ static int pc263_detach(struct comedi_device *dev) } else #endif { +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA if (dev->iobase) release_region(dev->iobase, PC263_IO_SIZE); +#endif } } - if (dev->board_name) { - printk(KERN_INFO "comedi%d: %s removed\n", - dev->minor, dev->board_name); - } - return 0; } /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. */ +#ifdef CONFIG_COMEDI_AMPLC_PC263_ISA static int pc263_request_region(unsigned minor, unsigned long from, unsigned long extent) { @@ -384,6 +392,7 @@ static int pc263_request_region(unsigned minor, unsigned long from, } return 0; } +#endif /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -429,12 +438,12 @@ static int pc263_dio_insn_config(struct comedi_device *dev, * A convenient macro that defines init_module() and cleanup_module(), * as necessary. */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_AMPLC_PC263_PCI static int __devinit driver_amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_amplc_pc263.driver_name); + return comedi_pci_auto_config(dev, &driver_amplc_pc263); } static void __devexit driver_amplc_pc263_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b278917c..fbf19ca 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -380,18 +380,6 @@ static const struct pci224_board pci224_boards[] = { }; /* - * PCI driver table. - */ - -static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, pci224_pci_table); - -/* * Useful for shorthand access to the particular board structure */ #define thisboard ((struct pci224_board *)dev->board_ptr) @@ -422,65 +410,6 @@ struct pci224_private { #define devpriv ((struct pci224_private *)dev->private) /* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pci224_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci224_detach(struct comedi_device *dev); -static struct comedi_driver driver_amplc_pci224 = { - .driver_name = DRIVER_NAME, - .module = THIS_MODULE, - .attach = pci224_attach, - .detach = pci224_detach, - .board_name = &pci224_boards[0].name, - .offset = sizeof(struct pci224_board), - .num_names = ARRAY_SIZE(pci224_boards), -}; - -static int __devinit driver_amplc_pci224_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) -{ - return comedi_pci_auto_config(dev, driver_amplc_pci224.driver_name); -} - -static void __devexit driver_amplc_pci224_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_amplc_pci224_pci_driver = { - .id_table = pci224_pci_table, - .probe = &driver_amplc_pci224_pci_probe, - .remove = __devexit_p(&driver_amplc_pci224_pci_remove) -}; - -static int __init driver_amplc_pci224_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_amplc_pci224); - if (retval < 0) - return retval; - - driver_amplc_pci224_pci_driver.name = - (char *)driver_amplc_pci224.driver_name; - return pci_register_driver(&driver_amplc_pci224_pci_driver); -} - -static void __exit driver_amplc_pci224_cleanup_module(void) -{ - pci_unregister_driver(&driver_amplc_pci224_pci_driver); - comedi_driver_unregister(&driver_amplc_pci224); -} - -module_init(driver_amplc_pci224_init_module); -module_exit(driver_amplc_pci224_cleanup_module); - -/* * Called from the 'insn_write' function to perform a single write. */ static void @@ -1312,6 +1241,20 @@ static irqreturn_t pci224_interrupt(int irq, void *d) } /* + * This function looks for a board matching the supplied PCI device. + */ +static const struct pci224_board +*pci224_find_pci_board(struct pci_dev *pci_dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) + if (pci_dev->device == pci224_boards[i].devid) + return &pci224_boards[i]; + return NULL; +} + +/* * This function looks for a PCI device matching the requested board name, * bus and slot. */ @@ -1336,17 +1279,12 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } if (thisboard->model == any_model) { /* Match any supported model. */ - int i; - - for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) { - if (pci_dev->device == pci224_boards[i].devid) { - /* Change board_ptr to matched board. */ - dev->board_ptr = &pci224_boards[i]; - break; - } - } - if (i == ARRAY_SIZE(pci224_boards)) + const struct pci224_board *board_ptr; + board_ptr = pci224_find_pci_board(pci_dev); + if (board_ptr == NULL) continue; + /* Change board_ptr to matched board. */ + dev->board_ptr = board_ptr; } else { /* Match specific model name. */ if (thisboard->devid != pci_dev->device) @@ -1370,35 +1308,16 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot, } /* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. + * Common part of attach and attach_pci. */ -static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int pci224_attach_common(struct comedi_device *dev, + struct pci_dev *pci_dev, int *options) { struct comedi_subdevice *s; - struct pci_dev *pci_dev; unsigned int irq; - int bus = 0, slot = 0; unsigned n; int ret; - printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME); - - bus = it->options[0]; - slot = it->options[1]; - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - return ret; - } - - ret = pci224_find_pci(dev, bus, slot, &pci_dev); - if (ret < 0) - return ret; - devpriv->pci_dev = pci_dev; ret = comedi_pci_enable(pci_dev, DRIVER_NAME); if (ret < 0) { @@ -1483,24 +1402,26 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!s->range_table_list) return -ENOMEM; - for (n = 2; n < 3 + s->n_chan; n++) { - if (it->options[n] < 0 || it->options[n] > 1) { - printk(KERN_WARNING "comedi%d: %s: warning! " - "bad options[%u]=%d\n", - dev->minor, DRIVER_NAME, n, - it->options[n]); + if (options) { + for (n = 2; n < 3 + s->n_chan; n++) { + if (options[n] < 0 || options[n] > 1) { + printk(KERN_WARNING + "comedi%d: %s: warning! bad options[%u]=%d\n", + dev->minor, DRIVER_NAME, n, + options[n]); + } } } for (n = 0; n < s->n_chan; n++) { - if (n < COMEDI_NDEVCONFOPTS - 3 && - it->options[3 + n] == 1) { - if (it->options[2] == 1) + if (n < COMEDI_NDEVCONFOPTS - 3 && options && + options[3 + n] == 1) { + if (options[2] == 1) range_table_list[n] = &range_pci234_ext; else range_table_list[n] = &range_bipolar5; } else { - if (it->options[2] == 1) { + if (options && options[2] == 1) { range_table_list[n] = &range_pci234_ext2; } else { @@ -1511,14 +1432,14 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->hwrange = hwrange_pci234; } else { /* PCI224 range options. */ - if (it->options[2] == 1) { + if (options && options[2] == 1) { s->range_table = &range_pci224_external; devpriv->hwrange = hwrange_pci224_external; } else { - if (it->options[2] != 0) { + if (options && options[2] != 0) { printk(KERN_WARNING "comedi%d: %s: warning! " "bad options[2]=%d\n", - dev->minor, DRIVER_NAME, it->options[2]); + dev->minor, DRIVER_NAME, options[2]); } s->range_table = &range_pci224_internal; devpriv->hwrange = hwrange_pci224_internal; @@ -1552,21 +1473,59 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pci224_detach(struct comedi_device *dev) +static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct pci_dev *pci_dev; + int bus, slot; + int ret; + + printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME); + + bus = it->options[0]; + slot = it->options[1]; + ret = alloc_private(dev, sizeof(struct pci224_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + + ret = pci224_find_pci(dev, bus, slot, &pci_dev); + if (ret < 0) + return ret; + + return pci224_attach_common(dev, pci_dev, it->options); +} + +static int +pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { - printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME); + int ret; + + printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor, + DRIVER_NAME, pci_name(pci_dev)); + + ret = alloc_private(dev, sizeof(struct pci224_private)); + if (ret < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } + dev->board_ptr = pci224_find_pci_board(pci_dev); + if (dev->board_ptr == NULL) { + printk(KERN_ERR + "comedi%d: %s: BUG! cannot determine board type!\n", + dev->minor, DRIVER_NAME); + return -EINVAL; + } + return pci224_attach_common(dev, pci_dev, NULL); +} + +static void pci224_detach(struct comedi_device *dev) +{ if (dev->irq) free_irq(dev->irq, dev); - if (dev->subdevices) { struct comedi_subdevice *s; @@ -1581,18 +1540,49 @@ static int pci224_detach(struct comedi_device *dev) if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); } } - if (dev->board_name) { - printk(KERN_INFO "comedi%d: %s removed\n", - dev->minor, dev->board_name); - } +} - return 0; +static struct comedi_driver amplc_pci224_driver = { + .driver_name = "amplc_pci224", + .module = THIS_MODULE, + .attach = pci224_attach, + .detach = pci224_detach, + .attach_pci = pci224_attach_pci, + .board_name = &pci224_boards[0].name, + .offset = sizeof(struct pci224_board), + .num_names = ARRAY_SIZE(pci224_boards), +}; + +static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev, + const struct pci_device_id + *ent) +{ + return comedi_pci_auto_config(dev, &lc_pci224_driver); } +static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table); + +static struct pci_driver amplc_pci224_pci_driver = { + .name = "amplc_pci224", + .id_table = amplc_pci224_pci_table, + .probe = amplc_pci224_pci_probe, + .remove = __devexit_p(amplc_pci224_pci_remove), +}; +module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 5389795..d4c80b1 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -500,13 +500,6 @@ static const struct pci230_board pci230_boards[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, pci230_pci_table); /* * Useful for shorthand access to the particular board structure */ @@ -595,65 +588,6 @@ static const struct comedi_lrange pci230_ao_range = { 2, { /* PCI230 daccon bipolar flag for each analogue output range. */ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 }; -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pci230_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci230_detach(struct comedi_device *dev); -static struct comedi_driver driver_amplc_pci230 = { - .driver_name = "amplc_pci230", - .module = THIS_MODULE, - .attach = pci230_attach, - .detach = pci230_detach, - .board_name = &pci230_boards[0].name, - .offset = sizeof(pci230_boards[0]), - .num_names = ARRAY_SIZE(pci230_boards), -}; - -static int __devinit driver_amplc_pci230_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) -{ - return comedi_pci_auto_config(dev, driver_amplc_pci230.driver_name); -} - -static void __devexit driver_amplc_pci230_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_amplc_pci230_pci_driver = { - .id_table = pci230_pci_table, - .probe = &driver_amplc_pci230_pci_probe, - .remove = __devexit_p(&driver_amplc_pci230_pci_remove) -}; - -static int __init driver_amplc_pci230_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_amplc_pci230); - if (retval < 0) - return retval; - - driver_amplc_pci230_pci_driver.name = - (char *)driver_amplc_pci230.driver_name; - return pci_register_driver(&driver_amplc_pci230_pci_driver); -} - -static void __exit driver_amplc_pci230_cleanup_module(void) -{ - pci_unregister_driver(&driver_amplc_pci230_pci_driver); - comedi_driver_unregister(&driver_amplc_pci230); -} - -module_init(driver_amplc_pci230_init_module); -module_exit(driver_amplc_pci230_cleanup_module); - static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -1003,35 +937,19 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pci230_detach(struct comedi_device *dev) +static void pci230_detach(struct comedi_device *dev) { - printk("comedi%d: amplc_pci230: remove\n", dev->minor); - if (dev->subdevices && thisboard->have_dio) - /* Clean up dio subdevice. */ subdev_8255_cleanup(dev, dev->subdevices + 2); - if (dev->irq) free_irq(dev->irq, dev); - if (devpriv) { if (devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); } } - - return 0; } static int get_resources(struct comedi_device *dev, unsigned int res_mask, @@ -3048,6 +2966,42 @@ static int pci230_ai_cancel(struct comedi_device *dev, return 0; } +static struct comedi_driver amplc_pci230_driver = { + .driver_name = "amplc_pci230", + .module = THIS_MODULE, + .attach = pci230_attach, + .detach = pci230_detach, + .board_name = &pci230_boards[0].name, + .offset = sizeof(pci230_boards[0]), + .num_names = ARRAY_SIZE(pci230_boards), +}; + +static int __devinit amplc_pci230_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &lc_pci230_driver); +} + +static void __devexit amplc_pci230_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, amplc_pci230_pci_table); + +static struct pci_driver amplc_pci230_pci_driver = { + .name = "amplc_pci230", + .id_table = amplc_pci230_pci_table, + .probe = amplc_pci230_pci_probe, + .remove = __devexit_p(amplc_pci230_pci_remove) +}; +module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 11cdaf2..fb9951a 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -97,16 +97,6 @@ union encvaluetype { #define C6XDIGIO_TIME_OUT 20 -static int c6xdigio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int c6xdigio_detach(struct comedi_device *dev); -struct comedi_driver driver_c6xdigio = { - .driver_name = "c6xdigio", - .module = THIS_MODULE, - .attach = c6xdigio_attach, - .detach = c6xdigio_detach, -}; - static void C6X_pwmInit(unsigned long baseAddr) { int timeout = 0; @@ -407,10 +397,6 @@ static void board_init(struct comedi_device *dev) } -/* static void board_halt(struct comedi_device *dev) { */ -/* C6X_pwmInit(dev->iobase); */ -/* } */ - /* options[0] - I/O port options[1] - irq @@ -500,36 +486,22 @@ static int c6xdigio_attach(struct comedi_device *dev, return 0; } -static int c6xdigio_detach(struct comedi_device *dev) +static void c6xdigio_detach(struct comedi_device *dev) { - /* board_halt(dev); may not need this */ - - printk(KERN_DEBUG "comedi%d: c6xdigio: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, C6XDIGIO_SIZE); - - /* Not using IRQ so I am not sure if I need this */ if (dev->irq) free_irq(dev->irq, dev); - pnp_unregister_driver(&c6xdigio_pnp_driver); - - return 0; -} - -static int __init driver_c6xdigio_init_module(void) -{ - return comedi_driver_register(&driver_c6xdigio); } -static void __exit driver_c6xdigio_cleanup_module(void) -{ - comedi_driver_unregister(&driver_c6xdigio); -} - -module_init(driver_c6xdigio_init_module); -module_exit(driver_c6xdigio_cleanup_module); +static struct comedi_driver c6xdigio_driver = { + .driver_name = "c6xdigio", + .module = THIS_MODULE, + .attach = c6xdigio_attach, + .detach = c6xdigio_detach, +}; +module_comedi_driver(c6xdigio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 49404f4..3515923 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -91,7 +91,7 @@ struct das16cs_private { static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int das16cs_detach(struct comedi_device *dev); +static void das16cs_detach(struct comedi_device *dev); static struct comedi_driver driver_das16cs = { .driver_name = "cb_das16_cs", .module = THIS_MODULE, @@ -255,15 +255,10 @@ static int das16cs_attach(struct comedi_device *dev, return 1; } -static int das16cs_detach(struct comedi_device *dev) +static void das16cs_detach(struct comedi_device *dev) { - dev_dbg(dev->hw_dev, "comedi%d: das16cs: remove\n", dev->minor); - if (dev->irq) free_irq(dev->irq, dev); - - - return 0; } static irqreturn_t das16cs_interrupt(int irq, void *d) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 7e4ffcf..ee9e084b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -405,20 +405,6 @@ static const struct cb_pcidas_board cb_pcidas_boards[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); - /* * Useful for shorthand access to the particular board structure */ @@ -462,22 +448,6 @@ struct cb_pcidas_private { */ #define devpriv ((struct cb_pcidas_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int cb_pcidas_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int cb_pcidas_detach(struct comedi_device *dev); -static struct comedi_driver driver_cb_pcidas = { - .driver_name = "cb_pcidas", - .module = THIS_MODULE, - .attach = cb_pcidas_attach, - .detach = cb_pcidas_detach, -}; - static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -756,26 +726,12 @@ found: return 1; } -/* - * cb_pcidas_detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int cb_pcidas_detach(struct comedi_device *dev) +static void cb_pcidas_detach(struct comedi_device *dev) { - if (devpriv) { if (devpriv->s5933_config) { - /* disable and clear interrupts on amcc s5933 */ outl(INTCSR_INBOX_INTR_STATUS, devpriv->s5933_config + AMCC_OP_REG_INTCSR); -#ifdef CB_PCIDAS_DEBUG - dev_dbg(dev->hw_dev, "detaching, incsr is 0x%x\n", - inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR)); -#endif } } if (dev->irq) @@ -787,8 +743,6 @@ static int cb_pcidas_detach(struct comedi_device *dev) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - - return 0; } /* @@ -1918,47 +1872,44 @@ static int nvram_read(struct comedi_device *dev, unsigned int address, return 0; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver cb_pcidas_driver = { + .driver_name = "cb_pcidas", + .module = THIS_MODULE, + .attach = cb_pcidas_attach, + .detach = cb_pcidas_detach, +}; + +static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); + return comedi_pci_auto_config(dev, &cb_pcidas_driver); } -static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) +static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_cb_pcidas_pci_driver = { - .id_table = cb_pcidas_pci_table, - .probe = &driver_cb_pcidas_pci_probe, - .remove = __devexit_p(&driver_cb_pcidas_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); -static int __init driver_cb_pcidas_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_cb_pcidas); - if (retval < 0) - return retval; - - driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name; - return pci_register_driver(&driver_cb_pcidas_pci_driver); -} - -static void __exit driver_cb_pcidas_cleanup_module(void) -{ - pci_unregister_driver(&driver_cb_pcidas_pci_driver); - comedi_driver_unregister(&driver_cb_pcidas); -} - -module_init(driver_cb_pcidas_init_module); -module_exit(driver_cb_pcidas_cleanup_module); +static struct pci_driver cb_pcidas_pci_driver = { + .name = "cb_pcidas", + .id_table = cb_pcidas_pci_table, + .probe = cb_pcidas_pci_probe, + .remove = __devexit_p(cb_pcidas_pci_remove) +}; +module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 915157d..9d0b875 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1026,31 +1026,6 @@ static const struct pcidas64_board pcidas64_boards[] = { #endif }; -static DEFINE_PCI_DEVICE_TABLE(pcidas64_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pcidas64_pci_table); - static inline struct pcidas64_board *board(const struct comedi_device *dev) { return (struct pcidas64_board *)dev->board_ptr; @@ -1127,21 +1102,6 @@ static inline struct pcidas64_private *priv(struct comedi_device *dev) return dev->private; } -/* - * The comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int detach(struct comedi_device *dev); -static struct comedi_driver driver_cb_pcidas = { - .driver_name = "cb_pcidas64", - .module = THIS_MODULE, - .attach = attach, - .detach = detach, -}; - static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -1216,44 +1176,6 @@ static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags); static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd); -static int __devinit driver_cb_pcidas_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_cb_pcidas.driver_name); -} - -static void __devexit driver_cb_pcidas_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_cb_pcidas_pci_driver = { - .id_table = pcidas64_pci_table, - .probe = &driver_cb_pcidas_pci_probe, - .remove = __devexit_p(&driver_cb_pcidas_pci_remove) -}; - -static int __init driver_cb_pcidas_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_cb_pcidas); - if (retval < 0) - return retval; - - driver_cb_pcidas_pci_driver.name = (char *)driver_cb_pcidas.driver_name; - return pci_register_driver(&driver_cb_pcidas_pci_driver); -} - -static void __exit driver_cb_pcidas_cleanup_module(void) -{ - pci_unregister_driver(&driver_cb_pcidas_pci_driver); - comedi_driver_unregister(&driver_cb_pcidas); -} - -module_init(driver_cb_pcidas_init_module); -module_exit(driver_cb_pcidas_cleanup_module); - static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { @@ -1781,7 +1703,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_dbg(dev->hw_dev, "Found %s on bus %i, slot %i\n", board(dev)->name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); - if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) { + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { dev_warn(dev->hw_dev, "failed to enable PCI device and request regions\n"); return -EIO; } @@ -1868,15 +1790,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int detach(struct comedi_device *dev) +static void detach(struct comedi_device *dev) { unsigned int i; @@ -1938,8 +1852,6 @@ static int detach(struct comedi_device *dev) } if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 4); - - return 0; } static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -4315,6 +4227,56 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, i2c_stop(dev); } +static struct comedi_driver cb_pcidas64_driver = { + .driver_name = "cb_pcidas64", + .module = THIS_MODULE, + .attach = attach, + .detach = detach, +}; + +static int __devinit cb_pcidas64_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &cb_pcidas64_driver); +} + +static void __devexit cb_pcidas64_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) }, + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table); + +static struct pci_driver cb_pcidas64_pci_driver = { + .name = "cb_pcidas64", + .id_table = cb_pcidas64_pci_table, + .probe = cb_pcidas64_pci_probe, + .remove = __devexit_p(cb_pcidas64_pci_remove), +}; +module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index abba220..25ebca1 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -51,9 +51,12 @@ Please report success/failure with other different cards to #include "comedi_pci.h" #include "8255.h" -#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */ + +/* PCI vendor number of ComputerBoards */ +#define PCI_VENDOR_ID_CB 0x1307 #define EEPROM_SIZE 128 /* number of entries in eeprom */ -#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */ +/* maximum number of ao channels for supported boards */ +#define MAX_AO_CHANNELS 8 /* PCI-DDA base addresses */ #define DIGITALIO_BADRINDEX 2 @@ -94,20 +97,26 @@ Please report success/failure with other different cards to #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ /* write bits */ -#define SERIAL_IN_BIT 0x1 /* serial data input for eeprom, caldacs, reference dac */ +/* serial data input for eeprom, caldacs, reference dac */ +#define SERIAL_IN_BIT 0x1 #define CAL_CHANNEL_MASK (0x7 << 1) #define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK) /* read bits */ #define CAL_COUNTER_MASK 0x1f -#define CAL_COUNTER_OVERFLOW_BIT 0x20 /* calibration counter overflow status bit */ -#define AO_BELOW_REF_BIT 0x40 /* analog output is less than reference dac voltage */ +/* calibration counter overflow status bit */ +#define CAL_COUNTER_OVERFLOW_BIT 0x20 +/* analog output is less than reference dac voltage */ +#define AO_BELOW_REF_BIT 0x40 #define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */ #define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */ #define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */ -#define DESELECT_REF_DAC_BIT 0x2 /* don't send serial data to MAX542 reference dac */ -#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) /* don't send serial data to caldac n */ -#define DUMMY_BIT 0x40 /* manual says to set this bit with no explanation */ +/* don't send serial data to MAX542 reference dac */ +#define DESELECT_REF_DAC_BIT 0x2 +/* don't send serial data to caldac n */ +#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) +/* manual says to set this bit with no explanation */ +#define DUMMY_BIT 0x40 #define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ @@ -195,26 +204,17 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); - /* * Useful for shorthand access to the particular board structure */ #define thisboard ((const struct cb_pcidda_board *)dev->board_ptr) -/* this structure is for data unique to this hardware driver. If - several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ +/* + * this structure is for data unique to this hardware driver. If + * several hardware drivers keep similar information in this structure, + * feel free to suggest moving the variable to the struct comedi_device + * struct. + */ struct cb_pcidda_private { int data; @@ -227,8 +227,10 @@ struct cb_pcidda_private { /* unsigned long control_status; */ /* unsigned long adc_fifo; */ - unsigned int dac_cal1_bits; /* bits last written to da calibration register 1 */ - unsigned int ao_range[MAX_AO_CHANNELS]; /* current range settings for output channels */ + /* bits last written to da calibration register 1 */ + unsigned int dac_cal1_bits; + /* current range settings for output channels */ + unsigned int ao_range[MAX_AO_CHANNELS]; u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; @@ -238,9 +240,6 @@ struct cb_pcidda_private { */ #define devpriv ((struct cb_pcidda_private *)dev->private) -static int cb_pcidda_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int cb_pcidda_detach(struct comedi_device *dev); /* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -259,19 +258,6 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, unsigned int range); /* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static struct comedi_driver driver_cb_pcidda = { - .driver_name = "cb_pcidda", - .module = THIS_MODULE, - .attach = cb_pcidda_attach, - .detach = cb_pcidda_detach, -}; - -/* * Attach is called by the Comedi core to configure the driver * for a particular board. */ @@ -377,7 +363,8 @@ found: dev_dbg(dev->hw_dev, "eeprom:\n"); for (index = 0; index < EEPROM_SIZE; index++) { devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->hw_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]); + dev_dbg(dev->hw_dev, "%i:0x%x\n", index, + devpriv->eeprom_data[index]); } /* set calibrations dacs */ @@ -387,19 +374,8 @@ found: return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int cb_pcidda_detach(struct comedi_device *dev) +static void cb_pcidda_detach(struct comedi_device *dev) { -/* - * Deallocate the I/O ports. - */ if (devpriv) { if (devpriv->pci_dev) { if (devpriv->dac) @@ -407,13 +383,10 @@ static int cb_pcidda_detach(struct comedi_device *dev) pci_dev_put(devpriv->pci_dev); } } - /* cleanup 8255 */ if (dev->subdevices) { subdev_8255_cleanup(dev, dev->subdevices + 1); subdev_8255_cleanup(dev, dev->subdevices + 2); } - - return 0; } /* @@ -484,7 +457,10 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique and mutually + * compatible + */ /* note that mutual compatibility is not an issue here */ if (cmd->scan_begin_src != TRIG_TIMER @@ -696,8 +672,10 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, unsigned int i; unsigned int cal2_bits; unsigned int value; - const int max_num_caldacs = 4; /* one caldac for every two dac channels */ - const int read_instruction = 0x6; /* bits to send to tell eeprom we want to read */ + /* one caldac for every two dac channels */ + const int max_num_caldacs = 4; + /* bits to send to tell eeprom we want to read */ + const int read_instruction = 0x6; const int instruction_length = 3; const int address_length = 8; @@ -729,9 +707,11 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, { unsigned int cal2_bits; unsigned int i; - const int num_channel_bits = 3; /* caldacs use 3 bit channel specification */ + /* caldacs use 3 bit channel specification */ + const int num_channel_bits = 3; const int num_caldac_bits = 8; /* 8 bit calibration dacs */ - const int max_num_caldacs = 4; /* one caldac for every two dac channels */ + /* one caldac for every two dac channels */ + const int max_num_caldacs = 4; /* write 3 bit channel */ cb_pcidda_serial_out(dev, channel, num_channel_bits); @@ -790,14 +770,20 @@ static unsigned int offset_eeprom_address(unsigned int ao_channel, return 0x7 + 2 * range + 12 * ao_channel; } -/* returns eeprom address that provides gain calibration for given ao channel and range */ +/* + * returns eeprom address that provides gain calibration for given ao + * channel and range + */ static unsigned int gain_eeprom_address(unsigned int ao_channel, unsigned int range) { return 0x8 + 2 * range + 12 * ao_channel; } -/* returns upper byte of eeprom entry, which gives the coarse adjustment values */ +/* + * returns upper byte of eeprom entry, which gives the coarse adjustment + * values + */ static unsigned int eeprom_coarse_byte(unsigned int word) { return (word >> 8) & 0xff; @@ -815,7 +801,7 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, { unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; - /* remember range so we can tell when we need to readjust calibration */ + /* remember range so we can tell when we need to readjust calibration */ devpriv->ao_range[channel] = range; /* get values from eeprom data */ @@ -843,47 +829,42 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, fine_gain_channel(channel), fine_gain); } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver cb_pcidda_driver = { + .driver_name = "cb_pcidda", + .module = THIS_MODULE, + .attach = cb_pcidda_attach, + .detach = cb_pcidda_detach, +}; + +static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name); + return comedi_pci_auto_config(dev, &cb_pcidda_driver); } -static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev) +static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_cb_pcidda_pci_driver = { - .id_table = cb_pcidda_pci_table, - .probe = &driver_cb_pcidda_pci_probe, - .remove = __devexit_p(&driver_cb_pcidda_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); -static int __init driver_cb_pcidda_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_cb_pcidda); - if (retval < 0) - return retval; - - driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name; - return pci_register_driver(&driver_cb_pcidda_pci_driver); -} - -static void __exit driver_cb_pcidda_cleanup_module(void) -{ - pci_unregister_driver(&driver_cb_pcidda_pci_driver); - comedi_driver_unregister(&driver_cb_pcidda); -} - -module_init(driver_cb_pcidda_init_module); -module_exit(driver_cb_pcidda_cleanup_module); +static struct pci_driver cb_pcidda_pci_driver = { + .name = "cb_pcidda", + .id_table = cb_pcidda_pci_table, + .probe = cb_pcidda_pci_probe, + .remove = __devexit_p(cb_pcidda_pci_remove), +}; +module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c index 8f32152..713132c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidio.c +++ b/drivers/staging/comedi/drivers/cb_pcidio.c @@ -86,19 +86,6 @@ static const struct pcidio_board pcidio_boards[] = { }, }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded - * upstream. */ -static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, pcidio_pci_table); - /* * Useful for shorthand access to the particular board structure */ @@ -125,59 +112,6 @@ struct pcidio_private { */ #define devpriv ((struct pcidio_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcidio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcidio_detach(struct comedi_device *dev); -static struct comedi_driver driver_cb_pcidio = { - .driver_name = "cb_pcidio", - .module = THIS_MODULE, - .attach = pcidio_attach, - .detach = pcidio_detach, - -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcidio_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - -/* The following fields should NOT be initialized if you are dealing - * with PCI devices - * - * .board_name = pcidio_boards, - * .offset = sizeof(struct pcidio_board), - * .num_names = sizeof(pcidio_boards) / sizeof(structpcidio_board), - */ - -}; - -/*------------------------------- FUNCTIONS -----------------------------------*/ - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pcidev = NULL; @@ -261,15 +195,7 @@ found: return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcidio_detach(struct comedi_device *dev) +static void pcidio_detach(struct comedi_device *dev) { if (devpriv) { if (devpriv->pci_dev) { @@ -283,50 +209,41 @@ static int pcidio_detach(struct comedi_device *dev) for (i = 0; i < thisboard->n_8255; i++) subdev_8255_cleanup(dev, dev->subdevices + i); } - return 0; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit driver_cb_pcidio_pci_probe(struct pci_dev *dev, +static struct comedi_driver cb_pcidio_driver = { + .driver_name = "cb_pcidio", + .module = THIS_MODULE, + .attach = pcidio_attach, + .detach = pcidio_detach, +}; + +static int __devinit cb_pcidio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcidio.driver_name); + return comedi_pci_auto_config(dev, &cb_pcidio_driver); } -static void __devexit driver_cb_pcidio_pci_remove(struct pci_dev *dev) +static void __devexit cb_pcidio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_cb_pcidio_pci_driver = { - .id_table = pcidio_pci_table, - .probe = &driver_cb_pcidio_pci_probe, - .remove = __devexit_p(&driver_cb_pcidio_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(cb_pcidio_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0028) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0014) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000b) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, cb_pcidio_pci_table); -static int __init driver_cb_pcidio_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_cb_pcidio); - if (retval < 0) - return retval; - - driver_cb_pcidio_pci_driver.name = (char *)driver_cb_pcidio.driver_name; - return pci_register_driver(&driver_cb_pcidio_pci_driver); -} - -static void __exit driver_cb_pcidio_cleanup_module(void) -{ - pci_unregister_driver(&driver_cb_pcidio_pci_driver); - comedi_driver_unregister(&driver_cb_pcidio); -} - -module_init(driver_cb_pcidio_init_module); -module_exit(driver_cb_pcidio_cleanup_module); +static struct pci_driver cb_pcidio_pci_driver = { + .name = "cb_pcidio", + .id_table = cb_pcidio_pci_table, + .probe = cb_pcidio_pci_probe, + .remove = __devexit_p(cb_pcidio_pci_remove), +}; +module_comedi_pci_driver(cb_pcidio_driver, cb_pcidio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 8ba6942..5f834d0 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -123,15 +123,6 @@ static const struct cb_pcimdas_board cb_pcimdas_boards[] = { }, }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); - #define N_BOARDS 1 /* Max number of boards supported */ /* @@ -139,9 +130,12 @@ MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); */ #define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr) -/* this structure is for data unique to this hardware driver. If - several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ +/* + * this structure is for data unique to this hardware driver. If + * several hardware drivers keep similar information in this structure, + * feel free to suggest moving the variable to the struct comedi_device + * struct. + */ struct cb_pcimdas_private { int data; @@ -172,22 +166,6 @@ struct cb_pcimdas_private { */ #define devpriv ((struct cb_pcimdas_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int cb_pcimdas_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int cb_pcimdas_detach(struct comedi_device *dev); -static struct comedi_driver driver_cb_pcimdas = { - .driver_name = "cb_pcimdas", - .module = THIS_MODULE, - .attach = cb_pcimdas_attach, - .detach = cb_pcimdas_detach, -}; - static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -317,7 +295,8 @@ found: s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->ao_nchan; s->maxdata = 1 << thisboard->ao_bits; - s->range_table = &range_unknown; /* ranges are hardware settable, but not software readable. */ + /* ranges are hardware settable, but not software readable. */ + s->range_table = &range_unknown; s->insn_write = &cb_pcimdas_ao_winsn; s->insn_read = &cb_pcimdas_ao_rinsn; @@ -331,29 +310,8 @@ found: return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int cb_pcimdas_detach(struct comedi_device *dev) +static void cb_pcimdas_detach(struct comedi_device *dev) { - if (devpriv) { - dev_dbg(dev->hw_dev, "devpriv->BADR0 = 0x%lx\n", - devpriv->BADR0); - dev_dbg(dev->hw_dev, "devpriv->BADR1 = 0x%lx\n", - devpriv->BADR1); - dev_dbg(dev->hw_dev, "devpriv->BADR2 = 0x%lx\n", - devpriv->BADR2); - dev_dbg(dev->hw_dev, "devpriv->BADR3 = 0x%lx\n", - devpriv->BADR3); - dev_dbg(dev->hw_dev, "devpriv->BADR4 = 0x%lx\n", - devpriv->BADR4); - } - if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { @@ -363,8 +321,6 @@ static int cb_pcimdas_detach(struct comedi_device *dev) pci_dev_put(devpriv->pci_dev); } } - - return 0; } /* @@ -402,7 +358,10 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, outb(0x01, devpriv->BADR3 + 6); /* set bursting off, conversions on */ outb(0x00, devpriv->BADR3 + 7); /* set range to 10V. UP/BP is controlled by a switch on the board */ - /* write channel limits to multiplexer, set Low (bits 0-3) and High (bits 4-7) channels to chan. */ + /* + * write channel limits to multiplexer, set Low (bits 0-3) and + * High (bits 4-7) channels to chan. + */ chanlims = chan | (chan << 4); outb(chanlims, devpriv->BADR3 + 0); @@ -479,49 +438,37 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit driver_cb_pcimdas_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static struct comedi_driver cb_pcimdas_driver = { + .driver_name = "cb_pcimdas", + .module = THIS_MODULE, + .attach = cb_pcimdas_attach, + .detach = cb_pcimdas_detach, +}; + +static int __devinit cb_pcimdas_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_cb_pcimdas.driver_name); + return comedi_pci_auto_config(dev, &cb_pcimdas_driver); } -static void __devexit driver_cb_pcimdas_pci_remove(struct pci_dev *dev) +static void __devexit cb_pcimdas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_cb_pcimdas_pci_driver = { - .id_table = cb_pcimdas_pci_table, - .probe = &driver_cb_pcimdas_pci_probe, - .remove = __devexit_p(&driver_cb_pcimdas_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); -static int __init driver_cb_pcimdas_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_cb_pcimdas); - if (retval < 0) - return retval; - - driver_cb_pcimdas_pci_driver.name = - (char *)driver_cb_pcimdas.driver_name; - return pci_register_driver(&driver_cb_pcimdas_pci_driver); -} - -static void __exit driver_cb_pcimdas_cleanup_module(void) -{ - pci_unregister_driver(&driver_cb_pcimdas_pci_driver); - comedi_driver_unregister(&driver_cb_pcimdas); -} - -module_init(driver_cb_pcimdas_init_module); -module_exit(driver_cb_pcimdas_cleanup_module); +static struct pci_driver cb_pcimdas_pci_driver = { + .name = "cb_pcimdas", + .id_table = cb_pcimdas_pci_table, + .probe = cb_pcimdas_pci_probe, + .remove = __devexit_p(cb_pcimdas_pci_remove), +}; +module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 40bddfa..b339685 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -140,17 +140,6 @@ static const struct board_struct boards[] = { #define REG_SZ (thisboard->reg_sz) #define REGS_BADRINDEX (thisboard->regs_badrindex) -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded - * upstream. */ -static DEFINE_PCI_DEVICE_TABLE(pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, pci_table); - /* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, @@ -161,7 +150,6 @@ struct board_private_struct { unsigned long registers; /* set by probe */ unsigned long dio_registers; char attached_to_8255; /* boolean */ - char attached_successfully; /* boolean */ /* would be useful for a PCI device */ struct pci_dev *pci_dev; @@ -177,66 +165,6 @@ struct board_private_struct { */ #define devpriv ((struct board_private_struct *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int detach(struct comedi_device *dev); -static struct comedi_driver cb_pcimdda_driver = { - .driver_name = "cb_pcimdda", - .module = THIS_MODULE, - .attach = attach, - .detach = detach, -}; - -MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>"); -MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA " - "series. Currently only supports PCIM-DDA06-16 (which " - "also happens to be the only board in this series. :) ) "); -MODULE_LICENSE("GPL"); -static int __devinit cb_pcimdda_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) -{ - return comedi_pci_auto_config(dev, cb_pcimdda_driver.driver_name); -} - -static void __devexit cb_pcimdda_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver cb_pcimdda_driver_pci_driver = { - .id_table = pci_table, - .probe = &cb_pcimdda_driver_pci_probe, - .remove = __devexit_p(&cb_pcimdda_driver_pci_remove) -}; - -static int __init cb_pcimdda_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&cb_pcimdda_driver); - if (retval < 0) - return retval; - - cb_pcimdda_driver_pci_driver.name = - (char *)cb_pcimdda_driver.driver_name; - return pci_register_driver(&cb_pcimdda_driver_pci_driver); -} - -static void __exit cb_pcimdda_driver_cleanup_module(void) -{ - pci_unregister_driver(&cb_pcimdda_driver_pci_driver); - comedi_driver_unregister(&cb_pcimdda_driver); -} - -module_init(cb_pcimdda_driver_init_module); -module_exit(cb_pcimdda_driver_cleanup_module); - static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -354,44 +282,24 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - devpriv->attached_successfully = 1; - printk("attached\n"); return 1; } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int detach(struct comedi_device *dev) +static void detach(struct comedi_device *dev) { if (devpriv) { - if (dev->subdevices && devpriv->attached_to_8255) { - /* de-register us from the 8255 driver */ subdev_8255_cleanup(dev, dev->subdevices + 2); devpriv->attached_to_8255 = 0; } - if (devpriv->pci_dev) { if (devpriv->registers) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - - if (devpriv->attached_successfully && thisboard) - printk("comedi%d: %s: detached\n", dev->minor, - thisboard->name); - } - - return 0; } static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -515,3 +423,41 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it) "card found at the requested position\n"); return -ENODEV; } + +static struct comedi_driver cb_pcimdda_driver = { + .driver_name = "cb_pcimdda", + .module = THIS_MODULE, + .attach = attach, + .detach = detach, +}; + +static int __devinit cb_pcimdda_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &cb_pcimdda_driver); +} + +static void __devexit cb_pcimdda_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table); + +static struct pci_driver cb_pcimdda_driver_pci_driver = { + .name = "cb_pcimdda", + .id_table = cb_pcimdda_pci_table, + .probe = cb_pcimdda_pci_probe, + .remove = __devexit_p(cb_pcimdda_pci_remove), +}; +module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver); + +MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>"); +MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA " + "series. Currently only supports PCIM-DDA06-16 (which " + "also happens to be the only board in this series. :) ) "); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index d8aefb2..29412de 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -60,7 +60,6 @@ Configuration Options: #define MAX_CHANS 256 #define MODULE_NAME "comedi_bond" -MODULE_LICENSE("GPL"); #ifndef STR # define STR1(x) #x # define STR(x) STR1(x) @@ -79,10 +78,6 @@ MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful" } while (0) #define WARNING(x...) printk(KERN_WARNING MODULE_NAME ": WARNING: "x) #define ERROR(x...) printk(KERN_ERR MODULE_NAME ": INTERNAL ERROR: "x) -MODULE_AUTHOR("Calin A. Culianu"); -MODULE_DESCRIPTION(MODULE_NAME "A driver for COMEDI to bond multiple COMEDI " - "devices together as one. In the words of John Lennon: " - "'And the world will live as one...'"); /* * Board descriptions for two imaginary boards. Describing the @@ -93,12 +88,6 @@ struct BondingBoard { const char *name; }; -static const struct BondingBoard bondingBoards[] = { - { - .name = MODULE_NAME, - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -133,129 +122,6 @@ struct Private { */ #define devpriv ((struct Private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int bonding_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int bonding_detach(struct comedi_device *dev); -/** Build Private array of all devices.. */ -static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it); -static void doDevUnconfig(struct comedi_device *dev); -/* Ugly implementation of realloc that always copies memory around -- I'm lazy, - * what can I say? I like to do wasteful memcopies.. :) */ -static void *Realloc(const void *ptr, size_t len, size_t old_len); - -static struct comedi_driver driver_bonding = { - .driver_name = MODULE_NAME, - .module = THIS_MODULE, - .attach = bonding_attach, - .detach = bonding_detach, - /* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in skel_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &bondingBoards[0].name, - .offset = sizeof(struct BondingBoard), - .num_names = ARRAY_SIZE(bondingBoards), -}; - -static int bonding_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int bonding_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int bonding_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - - LOG_MSG("comedi%d\n", dev->minor); - - /* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct Private)) < 0) - return -ENOMEM; - - /* - * Setup our bonding from config params.. sets up our Private struct.. - */ - if (!doDevConfig(dev, it)) - return -EINVAL; - - /* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = devpriv->name; - - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = devpriv->nchans; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = bonding_dio_insn_bits; - s->insn_config = bonding_dio_insn_config; - - LOG_MSG("attached with %u DIO channels coming from %u different " - "subdevices all bonded together. " - "John Lennon would be proud!\n", - devpriv->nchans, devpriv->ndevs); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int bonding_detach(struct comedi_device *dev) -{ - LOG_MSG("comedi%d: remove\n", dev->minor); - doDevUnconfig(dev); - return 0; -} - /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more * useful to applications if you implement the insn_bits interface. @@ -466,7 +332,57 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -static void doDevUnconfig(struct comedi_device *dev) +static int bonding_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + + LOG_MSG("comedi%d\n", dev->minor); + + /* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct Private)) < 0) + return -ENOMEM; + + /* + * Setup our bonding from config params.. sets up our Private struct.. + */ + if (!doDevConfig(dev, it)) + return -EINVAL; + + /* + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. + */ + dev->board_name = devpriv->name; + + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = devpriv->nchans; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = bonding_dio_insn_bits; + s->insn_config = bonding_dio_insn_config; + + LOG_MSG("attached with %u DIO channels coming from %u different " + "subdevices all bonded together. " + "John Lennon would be proud!\n", + devpriv->nchans, devpriv->ndevs); + + return 1; +} + +static void bonding_detach(struct comedi_device *dev) { unsigned long devs_closed = 0; @@ -490,15 +406,25 @@ static void doDevUnconfig(struct comedi_device *dev) } } -static int __init init(void) -{ - return comedi_driver_register(&driver_bonding); -} +static const struct BondingBoard bondingBoards[] = { + { + .name = "comedi_bond", + }, +}; -static void __exit cleanup(void) -{ - comedi_driver_unregister(&driver_bonding); -} +static struct comedi_driver bonding_driver = { + .driver_name = "comedi_bond", + .module = THIS_MODULE, + .attach = bonding_attach, + .detach = bonding_detach, + .board_name = &bondingBoards[0].name, + .offset = sizeof(struct BondingBoard), + .num_names = ARRAY_SIZE(bondingBoards), +}; +module_comedi_driver(bonding_driver); -module_init(init); -module_exit(cleanup); +MODULE_AUTHOR("Calin A. Culianu"); +MODULE_DESCRIPTION(MODULE_NAME "A driver for COMEDI to bond multiple COMEDI " + "devices together as one. In the words of John Lennon: " + "'And the world will live as one...'"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 21d834d..bff5dcd 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -91,29 +91,6 @@ pin, which can be used to wake up tasks. #define PARPORT_B 1 #define PARPORT_C 2 -static int parport_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int parport_detach(struct comedi_device *dev); -static struct comedi_driver driver_parport = { - .driver_name = "comedi_parport", - .module = THIS_MODULE, - .attach = parport_attach, - .detach = parport_detach, -}; - -static int __init driver_parport_init_module(void) -{ - return comedi_driver_register(&driver_parport); -} - -static void __exit driver_parport_cleanup_module(void) -{ - comedi_driver_unregister(&driver_parport); -} - -module_init(driver_parport_init_module); -module_exit(driver_parport_cleanup_module); - struct parport_private { unsigned int a_data; unsigned int c_data; @@ -395,19 +372,22 @@ static int parport_attach(struct comedi_device *dev, return 1; } -static int parport_detach(struct comedi_device *dev) +static void parport_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: parport: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, PARPORT_SIZE); - if (dev->irq) free_irq(dev->irq, dev); - - return 0; } +static struct comedi_driver parport_driver = { + .driver_name = "comedi_parport", + .module = THIS_MODULE, + .attach = parport_attach, + .detach = parport_detach, +}; +module_comedi_driver(parport_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index a804742..873e374 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -67,15 +67,6 @@ struct waveform_board { #define N_CHANS 8 -static const struct waveform_board waveform_boards[] = { - { - .name = "comedi_test", - .ai_chans = N_CHANS, - .ai_bits = 16, - .have_dio = 0, - }, -}; - #define thisboard ((const struct waveform_board *)dev->board_ptr) /* Data unique to this driver */ @@ -94,54 +85,6 @@ struct waveform_private { }; #define devpriv ((struct waveform_private *)dev->private) -static int waveform_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int waveform_detach(struct comedi_device *dev); -static struct comedi_driver driver_waveform = { - .driver_name = "comedi_test", - .module = THIS_MODULE, - .attach = waveform_attach, - .detach = waveform_detach, - .board_name = &waveform_boards[0].name, - .offset = sizeof(struct waveform_board), - .num_names = ARRAY_SIZE(waveform_boards), -}; - -static int __init driver_waveform_init_module(void) -{ - return comedi_driver_register(&driver_waveform); -} - -static void __exit driver_waveform_cleanup_module(void) -{ - comedi_driver_unregister(&driver_waveform); -} - -module_init(driver_waveform_init_module); -module_exit(driver_waveform_cleanup_module); - -static int waveform_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int waveform_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); -static int waveform_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static int waveform_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int waveform_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static short fake_sawtooth(struct comedi_device *dev, unsigned int range, - unsigned long current_time); -static short fake_squarewave(struct comedi_device *dev, unsigned int range, - unsigned long current_time); -static short fake_flatline(struct comedi_device *dev, unsigned int range, - unsigned long current_time); -static short fake_waveform(struct comedi_device *dev, unsigned int channel, - unsigned int range, unsigned long current_time); - /* 1000 nanosec in a microsec */ static const int nano_per_micro = 1000; @@ -154,6 +97,78 @@ static const struct comedi_lrange waveform_ai_ranges = { } }; +static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index, + unsigned long current_time) +{ + struct comedi_subdevice *s = dev->read_subdev; + unsigned int offset = s->maxdata / 2; + u64 value; + const struct comedi_krange *krange = + &s->range_table->range[range_index]; + u64 binary_amplitude; + + binary_amplitude = s->maxdata; + binary_amplitude *= devpriv->uvolt_amplitude; + do_div(binary_amplitude, krange->max - krange->min); + + current_time %= devpriv->usec_period; + value = current_time; + value *= binary_amplitude * 2; + do_div(value, devpriv->usec_period); + value -= binary_amplitude; /* get rid of sawtooth's dc offset */ + + return offset + value; +} + +static short fake_squarewave(struct comedi_device *dev, + unsigned int range_index, + unsigned long current_time) +{ + struct comedi_subdevice *s = dev->read_subdev; + unsigned int offset = s->maxdata / 2; + u64 value; + const struct comedi_krange *krange = + &s->range_table->range[range_index]; + current_time %= devpriv->usec_period; + + value = s->maxdata; + value *= devpriv->uvolt_amplitude; + do_div(value, krange->max - krange->min); + + if (current_time < devpriv->usec_period / 2) + value *= -1; + + return offset + value; +} + +static short fake_flatline(struct comedi_device *dev, unsigned int range_index, + unsigned long current_time) +{ + return dev->read_subdev->maxdata / 2; +} + +/* generates a different waveform depending on what channel is read */ +static short fake_waveform(struct comedi_device *dev, unsigned int channel, + unsigned int range, unsigned long current_time) +{ + enum { + SAWTOOTH_CHAN, + SQUARE_CHAN, + }; + switch (channel) { + case SAWTOOTH_CHAN: + return fake_sawtooth(dev, range, current_time); + break; + case SQUARE_CHAN: + return fake_squarewave(dev, range, current_time); + break; + default: + break; + } + + return fake_flatline(dev, range, current_time); +} + /* This is the background routine used to generate arbitrary data. It should run in the background; therefore it is scheduled by @@ -217,84 +232,6 @@ static void waveform_ai_interrupt(unsigned long arg) comedi_event(dev, dev->read_subdev); } -static int waveform_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int amplitude = it->options[0]; - int period = it->options[1]; - int i; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct waveform_private)) < 0) - return -ENOMEM; - - /* set default amplitude and period */ - if (amplitude <= 0) - amplitude = 1000000; /* 1 volt */ - if (period <= 0) - period = 100000; /* 0.1 sec */ - - devpriv->uvolt_amplitude = amplitude; - devpriv->usec_period = period; - - dev->n_subdevices = 2; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - dev->read_subdev = s; - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = &waveform_ai_ranges; - s->len_chanlist = s->n_chan * 2; - s->insn_read = waveform_ai_insn_read; - s->do_cmd = waveform_ai_cmd; - s->do_cmdtest = waveform_ai_cmdtest; - s->cancel = waveform_ai_cancel; - - s = dev->subdevices + 1; - dev->write_subdev = s; - /* analog output subdevice (loopback) */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = &waveform_ai_ranges; - s->len_chanlist = s->n_chan * 2; - s->insn_write = waveform_ao_insn_write; - s->do_cmd = NULL; - s->do_cmdtest = NULL; - s->cancel = NULL; - - /* Our default loopback value is just a 0V flatline */ - for (i = 0; i < s->n_chan; i++) - devpriv->ao_loopbacks[i] = s->maxdata / 2; - - init_timer(&(devpriv->timer)); - devpriv->timer.function = waveform_ai_interrupt; - devpriv->timer.data = (unsigned long)dev; - - printk(KERN_INFO "comedi%d: comedi_test: " - "%i microvolt, %li microsecond waveform attached\n", dev->minor, - devpriv->uvolt_amplitude, devpriv->usec_period); - return 1; -} - -static int waveform_detach(struct comedi_device *dev) -{ - printk("comedi%d: comedi_test: remove\n", dev->minor); - - if (dev->private) - waveform_ai_cancel(dev, dev->read_subdev); - - return 0; -} - static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) @@ -465,78 +402,6 @@ static int waveform_ai_cancel(struct comedi_device *dev, return 0; } -static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index, - unsigned long current_time) -{ - struct comedi_subdevice *s = dev->read_subdev; - unsigned int offset = s->maxdata / 2; - u64 value; - const struct comedi_krange *krange = - &s->range_table->range[range_index]; - u64 binary_amplitude; - - binary_amplitude = s->maxdata; - binary_amplitude *= devpriv->uvolt_amplitude; - do_div(binary_amplitude, krange->max - krange->min); - - current_time %= devpriv->usec_period; - value = current_time; - value *= binary_amplitude * 2; - do_div(value, devpriv->usec_period); - value -= binary_amplitude; /* get rid of sawtooth's dc offset */ - - return offset + value; -} - -static short fake_squarewave(struct comedi_device *dev, - unsigned int range_index, - unsigned long current_time) -{ - struct comedi_subdevice *s = dev->read_subdev; - unsigned int offset = s->maxdata / 2; - u64 value; - const struct comedi_krange *krange = - &s->range_table->range[range_index]; - current_time %= devpriv->usec_period; - - value = s->maxdata; - value *= devpriv->uvolt_amplitude; - do_div(value, krange->max - krange->min); - - if (current_time < devpriv->usec_period / 2) - value *= -1; - - return offset + value; -} - -static short fake_flatline(struct comedi_device *dev, unsigned int range_index, - unsigned long current_time) -{ - return dev->read_subdev->maxdata / 2; -} - -/* generates a different waveform depending on what channel is read */ -static short fake_waveform(struct comedi_device *dev, unsigned int channel, - unsigned int range, unsigned long current_time) -{ - enum { - SAWTOOTH_CHAN, - SQUARE_CHAN, - }; - switch (channel) { - case SAWTOOTH_CHAN: - return fake_sawtooth(dev, range, current_time); - break; - case SQUARE_CHAN: - return fake_squarewave(dev, range, current_time); - break; - default: - break; - } - - return fake_flatline(dev, range, current_time); -} - static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -561,6 +426,100 @@ static int waveform_ao_insn_write(struct comedi_device *dev, return insn->n; } +static int waveform_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int amplitude = it->options[0]; + int period = it->options[1]; + int i; + + dev->board_name = thisboard->name; + + if (alloc_private(dev, sizeof(struct waveform_private)) < 0) + return -ENOMEM; + + /* set default amplitude and period */ + if (amplitude <= 0) + amplitude = 1000000; /* 1 volt */ + if (period <= 0) + period = 100000; /* 0.1 sec */ + + devpriv->uvolt_amplitude = amplitude; + devpriv->usec_period = period; + + dev->n_subdevices = 2; + if (alloc_subdevices(dev, dev->n_subdevices) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + dev->read_subdev = s; + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + s->n_chan = thisboard->ai_chans; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = &waveform_ai_ranges; + s->len_chanlist = s->n_chan * 2; + s->insn_read = waveform_ai_insn_read; + s->do_cmd = waveform_ai_cmd; + s->do_cmdtest = waveform_ai_cmdtest; + s->cancel = waveform_ai_cancel; + + s = dev->subdevices + 1; + dev->write_subdev = s; + /* analog output subdevice (loopback) */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND; + s->n_chan = thisboard->ai_chans; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = &waveform_ai_ranges; + s->len_chanlist = s->n_chan * 2; + s->insn_write = waveform_ao_insn_write; + s->do_cmd = NULL; + s->do_cmdtest = NULL; + s->cancel = NULL; + + /* Our default loopback value is just a 0V flatline */ + for (i = 0; i < s->n_chan; i++) + devpriv->ao_loopbacks[i] = s->maxdata / 2; + + init_timer(&(devpriv->timer)); + devpriv->timer.function = waveform_ai_interrupt; + devpriv->timer.data = (unsigned long)dev; + + printk(KERN_INFO "comedi%d: comedi_test: " + "%i microvolt, %li microsecond waveform attached\n", dev->minor, + devpriv->uvolt_amplitude, devpriv->usec_period); + return 1; +} + +static void waveform_detach(struct comedi_device *dev) +{ + if (dev->private) + waveform_ai_cancel(dev, dev->read_subdev); +} + +static const struct waveform_board waveform_boards[] = { + { + .name = "comedi_test", + .ai_chans = N_CHANS, + .ai_bits = 16, + .have_dio = 0, + }, +}; + +static struct comedi_driver waveform_driver = { + .driver_name = "comedi_test", + .module = THIS_MODULE, + .attach = waveform_attach, + .detach = waveform_detach, + .board_name = &waveform_boards[0].name, + .offset = sizeof(struct waveform_board), + .num_names = ARRAY_SIZE(waveform_boards), +}; +module_comedi_driver(waveform_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index e3659bd..b8bac80 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -56,13 +56,6 @@ static const struct contec_board contec_boards[] = { }; #define PCI_DEVICE_ID_PIO1616L 0x8172 -static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L), - .driver_data = PIO1616L }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, contec_pci_table); #define thisboard ((const struct contec_board *)dev->board_ptr) @@ -75,30 +68,42 @@ struct contec_private { #define devpriv ((struct contec_private *)dev->private) -static int contec_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int contec_detach(struct comedi_device *dev); -static struct comedi_driver driver_contec = { - .driver_name = "contec_pci_dio", - .module = THIS_MODULE, - .attach = contec_attach, - .detach = contec_detach, -}; +static int contec_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + + dev_dbg(dev->hw_dev, "contec_do_insn_bits called\n"); + dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); + + if (insn->n != 2) + return -EINVAL; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + dev_dbg(dev->hw_dev, "out: %d on %lx\n", s->state, + dev->iobase + thisboard->out_offs); + outw(s->state, dev->iobase + thisboard->out_offs); + } + return 2; +} -/* Classic digital IO */ static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int contec_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); + struct comedi_insn *insn, unsigned int *data) +{ + + dev_dbg(dev->hw_dev, "contec_di_insn_bits called\n"); + dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); -#if 0 -static int contec_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); + if (insn->n != 2) + return -EINVAL; -static int contec_ns_to_timer(unsigned int *ns, int round); -#endif + data[1] = inw(dev->iobase + thisboard->in_offs); + + return 2; +} static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -164,107 +169,47 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } -static int contec_detach(struct comedi_device *dev) +static void contec_detach(struct comedi_device *dev) { - printk("comedi%d: contec: remove\n", dev->minor); - if (devpriv && devpriv->pci_dev) { if (dev->iobase) comedi_pci_disable(devpriv->pci_dev); pci_dev_put(devpriv->pci_dev); } - - return 0; -} - -#if 0 -static int contec_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - printk("contec_cmdtest called\n"); - return 0; -} - -static int contec_ns_to_timer(unsigned int *ns, int round) -{ - return *ns; -} -#endif - -static int contec_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - dev_dbg(dev->hw_dev, "contec_do_insn_bits called\n"); - dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - if (data[0]) { - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - dev_dbg(dev->hw_dev, "out: %d on %lx\n", s->state, - dev->iobase + thisboard->out_offs); - outw(s->state, dev->iobase + thisboard->out_offs); - } - return 2; } -static int contec_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - - dev_dbg(dev->hw_dev, "contec_di_insn_bits called\n"); - dev_dbg(dev->hw_dev, "data: %d %d\n", data[0], data[1]); - - if (insn->n != 2) - return -EINVAL; - - data[1] = inw(dev->iobase + thisboard->in_offs); - - return 2; -} +static struct comedi_driver contec_pci_dio_driver = { + .driver_name = "contec_pci_dio", + .module = THIS_MODULE, + .attach = contec_attach, + .detach = contec_detach, +}; -static int __devinit driver_contec_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit contec_pci_dio_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_contec.driver_name); + return comedi_pci_auto_config(dev, &contec_pci_dio_driver); } -static void __devexit driver_contec_pci_remove(struct pci_dev *dev) +static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_contec_pci_driver = { - .id_table = contec_pci_table, - .probe = &driver_contec_pci_probe, - .remove = __devexit_p(&driver_contec_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L), + .driver_data = PIO1616L }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, contec_pci_dio_pci_table); -static int __init driver_contec_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_contec); - if (retval < 0) - return retval; - - driver_contec_pci_driver.name = (char *)driver_contec.driver_name; - return pci_register_driver(&driver_contec_pci_driver); -} - -static void __exit driver_contec_cleanup_module(void) -{ - pci_unregister_driver(&driver_contec_pci_driver); - comedi_driver_unregister(&driver_contec); -} - -module_init(driver_contec_init_module); -module_exit(driver_contec_cleanup_module); +static struct pci_driver contec_pci_dio_pci_driver = { + .name = "contec_pci_dio", + .id_table = contec_pci_dio_pci_table, + .probe = contec_pci_dio_pci_probe, + .remove = __devexit_p(contec_pci_dio_pci_remove), +}; +module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index e61c6a8..696b58c 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -301,17 +301,6 @@ struct daqboard2000_hw { #define DAQBOARD2000_PosRefDacSelect 0x0100 #define DAQBOARD2000_NegRefDacSelect 0x0000 -static int daqboard2000_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int daqboard2000_detach(struct comedi_device *dev); - -static struct comedi_driver driver_daqboard2000 = { - .driver_name = "daqboard2000", - .module = THIS_MODULE, - .attach = daqboard2000_attach, - .detach = daqboard2000_detach, -}; - struct daq200_boardtype { const char *name; int id; @@ -321,16 +310,8 @@ static const struct daq200_boardtype boardtypes[] = { {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct daq200_boardtype)) #define this_board ((const struct daq200_boardtype *)dev->board_ptr) -static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { - { PCI_DEVICE(0x1616, 0x0409) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table); - struct daqboard2000_private { enum { card_daqboard_2000 @@ -412,9 +393,12 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, DAQBOARD2000_AcqResetScanListFifo | DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe; - /* If pacer clock is not set to some high value (> 10 us), we - risk multiple samples to be put into the result FIFO. */ - fpga->acqPacerClockDivLow = 1000000; /* 1 second, should be long enough */ + /* + * If pacer clock is not set to some high value (> 10 us), we + * risk multiple samples to be put into the result FIFO. + */ + /* 1 second, should be long enough */ + fpga->acqPacerClockDivLow = 1000000; fpga->acqPacerClockDivHigh = 0; gain = CR_RANGE(insn->chanspec); @@ -761,7 +745,7 @@ static int daqboard2000_attach(struct comedi_device *dev, devpriv->pci_dev = card; id = ((u32) card-> subsystem_device << 16) | card->subsystem_vendor; - for (i = 0; i < n_boardtypes; i++) { + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { if (boardtypes[i].id == id) { dev_dbg(dev->hw_dev, "%s\n", boardtypes[i].name); @@ -852,14 +836,12 @@ out: return result; } -static int daqboard2000_detach(struct comedi_device *dev) +static void daqboard2000_detach(struct comedi_device *dev) { if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 2); - if (dev->irq) free_irq(dev->irq, dev); - if (devpriv) { if (devpriv->daq) iounmap(devpriv->daq); @@ -871,48 +853,39 @@ static int daqboard2000_detach(struct comedi_device *dev) pci_dev_put(devpriv->pci_dev); } } - return 0; } -static int __devinit driver_daqboard2000_pci_probe(struct pci_dev *dev, - const struct pci_device_id - *ent) +static struct comedi_driver daqboard2000_driver = { + .driver_name = "daqboard2000", + .module = THIS_MODULE, + .attach = daqboard2000_attach, + .detach = daqboard2000_detach, +}; + +static int __devinit daqboard2000_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_daqboard2000.driver_name); + return comedi_pci_auto_config(dev, &daqboard2000_driver); } -static void __devexit driver_daqboard2000_pci_remove(struct pci_dev *dev) +static void __devexit daqboard2000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_daqboard2000_pci_driver = { - .id_table = daqboard2000_pci_table, - .probe = &driver_daqboard2000_pci_probe, - .remove = __devexit_p(&driver_daqboard2000_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { + { PCI_DEVICE(0x1616, 0x0409) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table); -static int __init driver_daqboard2000_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_daqboard2000); - if (retval < 0) - return retval; - - driver_daqboard2000_pci_driver.name = - (char *)driver_daqboard2000.driver_name; - return pci_register_driver(&driver_daqboard2000_pci_driver); -} - -static void __exit driver_daqboard2000_cleanup_module(void) -{ - pci_unregister_driver(&driver_daqboard2000_pci_driver); - comedi_driver_unregister(&driver_daqboard2000); -} - -module_init(driver_daqboard2000_init_module); -module_exit(driver_daqboard2000_cleanup_module); +static struct pci_driver daqboard2000_pci_driver = { + .name = "daqboard2000", + .id_table = daqboard2000_pci_table, + .probe = daqboard2000_pci_probe, + .remove = __devexit_p(daqboard2000_pci_remove), +}; +module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index c2dd0ed..1f31943 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -61,6 +61,20 @@ #define DRV_NAME "das08" +#ifdef CONFIG_COMEDI_DAS08_ISA_MODULE +#define CONFIG_COMEDI_DAS08_ISA +#endif +#ifdef CONFIG_COMEDI_DAS08_PCI_MODULE +#define CONFIG_COMEDI_DAS08_PCI +#endif +#ifdef CONFIG_COMEDI_DAS08_CS_MODULE +#define CONFIG_COMEDI_DAS08_CS +#endif + +#if defined(CONFIG_COMEDI_DAS08_ISA) || defined(CONFIG_COMEDI_DAS08_PCI) +#define DO_COMEDI_DRIVER_REGISTER +#endif + #define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 #define PCIDAS08_SIZE 0x54 @@ -160,6 +174,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); @@ -172,6 +187,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); +#endif static void i8254_set_mode_low(unsigned int base, int channel, unsigned int mode); @@ -253,7 +269,9 @@ static const int *const das08_gainlists[] = { das08_pgm_gainlist, }; +#ifdef DO_COMEDI_DRIVER_REGISTER static const struct das08_board_struct das08_boards[] = { +#ifdef CONFIG_COMEDI_DAS08_ISA { .name = "isa-das08", /* cio-das08.pdf */ .bustype = isa, @@ -395,25 +413,6 @@ static const struct das08_board_struct das08_boards[] = { .i8254_offset = 0x04, .iosize = 16, /* unchecked */ }, -#ifdef CONFIG_COMEDI_PCI - { - .name = "das08", /* pci-das08 */ - .id = PCI_DEVICE_ID_PCIDAS08, - .bustype = pci, - .ai = das08_ai_rinsn, - .ai_nbits = 12, - .ai_pg = das08_bipolar5, - .ai_encoding = das08_encode12, - .ao = NULL, - .ao_nbits = 0, - .di = das08_di_rbits, - .do_ = das08_do_wbits, - .do_nchan = 4, - .i8255_offset = 0, - .i8254_offset = 4, - .iosize = 8, - }, -#endif { .name = "pc104-das08", .bustype = pc104, @@ -462,9 +461,30 @@ static const struct das08_board_struct das08_boards[] = { .name = "das08-pga-g2", /* a KM board */ }, #endif +#endif /* CONFIG_COMEDI_DAS08_ISA */ +#ifdef CONFIG_COMEDI_DAS08_PCI + { + .name = "das08", /* pci-das08 */ + .id = PCI_DEVICE_ID_PCIDAS08, + .bustype = pci, + .ai = das08_ai_rinsn, + .ai_nbits = 12, + .ai_pg = das08_bipolar5, + .ai_encoding = das08_encode12, + .ao = NULL, + .ao_nbits = 0, + .di = das08_di_rbits, + .do_ = das08_do_wbits, + .do_nchan = 4, + .i8255_offset = 0, + .i8254_offset = 4, + .iosize = 8, + }, +#endif /* CONFIG_COMEDI_DAS08_PCI */ }; +#endif /* DO_COMEDI_DRIVER_REGISTER */ -#ifdef CONFIG_COMEDI_PCMCIA +#ifdef CONFIG_COMEDI_DAS08_CS struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { { .name = "pcm-das08", @@ -504,7 +524,7 @@ struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = { }; #endif -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, {0} @@ -619,6 +639,7 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return 2; } +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -628,7 +649,9 @@ static int das08jr_di_rbits(struct comedi_device *dev, return 2; } +#endif +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -643,7 +666,9 @@ static int das08jr_do_wbits(struct comedi_device *dev, return 2; } +#endif +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -672,6 +697,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, return n; } +#endif /* * @@ -679,6 +705,7 @@ static int das08jr_ao_winsn(struct comedi_device *dev, * a different method to force an update. * */ +#ifdef CONFIG_COMEDI_DAS08_ISA static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -707,6 +734,7 @@ static int das08ao_ao_winsn(struct comedi_device *dev, return n; } +#endif static unsigned int i8254_read_channel_low(unsigned int base, int chan) { @@ -842,6 +870,7 @@ static int das08_counter_config(struct comedi_device *dev, return 2; } +#ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it); static struct comedi_driver driver_das08 = { @@ -853,6 +882,7 @@ static struct comedi_driver driver_das08 = { .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), .offset = sizeof(struct das08_board_struct), }; +#endif int das08_common_attach(struct comedi_device *dev, unsigned long iobase) { @@ -972,11 +1002,12 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) } EXPORT_SYMBOL_GPL(das08_common_attach); +#ifdef DO_COMEDI_DRIVER_REGISTER static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; unsigned long iobase; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI unsigned long pci_iobase = 0; struct pci_dev *pdev = NULL; #endif @@ -986,9 +1017,9 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; printk(KERN_INFO "comedi%d: das08: ", dev->minor); +#ifdef CONFIG_COMEDI_DAS08_PCI /* deal with a pci board */ if (thisboard->bustype == pci) { -#ifdef CONFIG_COMEDI_PCI if (it->options[0] || it->options[1]) { printk("bus %i slot %i ", it->options[0], it->options[1]); @@ -1037,32 +1068,26 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable local interrupt 1 and pci interrupt */ outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); #endif -#else /* CONFIG_COMEDI_PCI */ - printk(KERN_ERR "this driver has not been built with PCI support.\n"); - return -EINVAL; -#endif /* CONFIG_COMEDI_PCI */ - } else { + } else +#endif /* CONFIG_COMEDI_DAS08_PCI */ + { iobase = it->options[0]; } printk(KERN_INFO "\n"); return das08_common_attach(dev, iobase); } +#endif /* DO_COMEDI_DRIVER_REGISTER */ - -int das08_common_detach(struct comedi_device *dev) +void das08_common_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: das08: remove\n", dev->minor); - if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 4); - - /* deallocate ioports for non-pcmcia, non-pci boards */ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) { if (dev->iobase) release_region(dev->iobase, thisboard->iosize); } -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI if (devpriv) { if (devpriv->pdev) { if (devpriv->pci_iobase) @@ -1072,16 +1097,14 @@ int das08_common_detach(struct comedi_device *dev) } } #endif - - return 0; } EXPORT_SYMBOL_GPL(das08_common_detach); -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_DAS08_PCI static int __devinit driver_das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_das08.driver_name); + return comedi_pci_auto_config(dev, &driver_das08); } static void __devexit driver_das08_pci_remove(struct pci_dev *dev) @@ -1094,43 +1117,38 @@ static struct pci_driver driver_das08_pci_driver = { .probe = &driver_das08_pci_probe, .remove = __devexit_p(&driver_das08_pci_remove) }; +#endif /* CONFIG_COMEDI_DAS08_PCI */ static int __init driver_das08_init_module(void) { - int retval; + int retval = 0; +#ifdef DO_COMEDI_DRIVER_REGISTER retval = comedi_driver_register(&driver_das08); if (retval < 0) return retval; - +#endif +#ifdef CONFIG_COMEDI_DAS08_PCI driver_das08_pci_driver.name = (char *)driver_das08.driver_name; - return pci_register_driver(&driver_das08_pci_driver); + retval = pci_register_driver(&driver_das08_pci_driver); +#endif + return retval; } static void __exit driver_das08_cleanup_module(void) { +#ifdef CONFIG_COMEDI_DAS08_PCI pci_unregister_driver(&driver_das08_pci_driver); +#endif +#ifdef DO_COMEDI_DRIVER_REGISTER comedi_driver_unregister(&driver_das08); +#endif } module_init(driver_das08_init_module); module_exit(driver_das08_cleanup_module); -#else -static int __init driver_das08_init_module(void) -{ - return comedi_driver_register(&driver_das08); -} - -static void __exit driver_das08_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das08); -} - -module_init(driver_das08_init_module); -module_exit(driver_das08_cleanup_module); -#endif -#ifdef CONFIG_COMEDI_PCMCIA +#ifdef CONFIG_COMEDI_DAS08_CS EXPORT_SYMBOL_GPL(das08_cs_boards); #endif diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index 2a30d76..0b92f24 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -74,6 +74,6 @@ struct das08_private_struct { extern struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS]; int das08_common_attach(struct comedi_device *dev, unsigned long iobase); -int das08_common_detach(struct comedi_device *dev); +void das08_common_detach(struct comedi_device *dev); #endif /* _DAS08_H */ diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index e7905ba..998444c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -339,38 +339,6 @@ struct munge_info { unsigned have_byte:1; }; -static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int das16_cmd_exec(struct comedi_device *dev, - struct comedi_subdevice *s); -static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static void das16_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *array, - unsigned int num_bytes, - unsigned int start_chan_index); - -static void das16_reset(struct comedi_device *dev); -static irqreturn_t das16_dma_interrupt(int irq, void *d); -static void das16_timer_interrupt(unsigned long arg); -static void das16_interrupt(struct comedi_device *dev); - -static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, - int flags); -static int das1600_mode_detect(struct comedi_device *dev); -static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, - struct comedi_cmd cmd); - -static void reg_dump(struct comedi_device *dev); - struct das16_board { const char *name; void *ai; @@ -389,344 +357,6 @@ struct das16_board { unsigned int id; }; -static const struct das16_board das16_boards[] = { - { - .name = "das-16", - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 15000, - .ai_pg = das16_pg_none, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x10, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0x00, - }, - { - .name = "das-16g", - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 15000, - .ai_pg = das16_pg_none, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x10, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0x00, - }, - { - .name = "das-16f", - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 8500, - .ai_pg = das16_pg_none, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x10, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0x00, - }, - { - .name = "cio-das16", /* cio-das16.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 20000, - .ai_pg = das16_pg_none, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x10, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0x80, - }, - { - .name = "cio-das16/f", /* das16.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_none, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x10, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0x80, - }, - { - .name = "cio-das16/jr", /* cio-das16jr.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 7692, - .ai_pg = das16_pg_16jr, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x10, - .id = 0x00, - }, - { - .name = "pc104-das16jr", /* pc104-das16jr_xx.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 3300, - .ai_pg = das16_pg_16jr, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x10, - .id = 0x00, - }, - { - .name = "cio-das16jr/16", /* cio-das16jr_16.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 16, - .ai_speed = 10000, - .ai_pg = das16_pg_16jr_16, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x10, - .id = 0x00, - }, - { - .name = "pc104-das16jr/16", /* pc104-das16jr_xx.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 16, - .ai_speed = 10000, - .ai_pg = das16_pg_16jr_16, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x10, - .id = 0x00, - }, - { - .name = "das-1201", /* 4924.pdf (keithley user's manual) */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 20000, - .ai_pg = das16_pg_none, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0x20, - }, - { - .name = "das-1202", /* 4924.pdf (keithley user's manual) */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_none, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0x20, - }, - { - /* 4919.pdf and 4922.pdf (keithley user's manual) */ - .name = "das-1401", - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_1601, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x0, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ - }, - { - /* 4919.pdf and 4922.pdf (keithley user's manual) */ - .name = "das-1402", - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_1602, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x0, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ - }, - { - .name = "das-1601", /* 4919.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_1601, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "das-1602", /* 4919.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_1602, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1401/12", /* cio-das1400_series.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 6250, - .ai_pg = das16_pg_1601, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1402/12", /* cio-das1400_series.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 6250, - .ai_pg = das16_pg_1602, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1402/16", /* cio-das1400_series.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 16, - .ai_speed = 10000, - .ai_pg = das16_pg_1602, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1601/12", /* cio-das160x-1x.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 6250, - .ai_pg = das16_pg_1601, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1602/12", /* cio-das160x-1x.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 10000, - .ai_pg = das16_pg_1602, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das1602/16", /* cio-das160x-1x.pdf */ - .ai = das16_ai_rinsn, - .ai_nbits = 16, - .ai_speed = 10000, - .ai_pg = das16_pg_1602, - .ao = das16_ao_winsn, - .ao_nbits = 12, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0x400, - .i8254_offset = 0x0c, - .size = 0x408, - .id = 0xc0}, - { - .name = "cio-das16/330", /* ? */ - .ai = das16_ai_rinsn, - .ai_nbits = 12, - .ai_speed = 3030, - .ai_pg = das16_pg_16jr, - .ao = NULL, - .di = das16_di_rbits, - .do_ = das16_do_wbits, - .i8255_offset = 0, - .i8254_offset = 0x0c, - .size = 0x14, - .id = 0xf0}, -#if 0 - { - .name = "das16/330i", /* ? */ - }, - { - .name = "das16/jr/ctr5", /* ? */ - }, - { - /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */ - .name = "cio-das16/m1/16", - }, -#endif -}; - -static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int das16_detach(struct comedi_device *dev); -static struct comedi_driver driver_das16 = { - .driver_name = "das16", - .module = THIS_MODULE, - .attach = das16_attach, - .detach = das16_detach, - .board_name = &das16_boards[0].name, - .num_names = ARRAY_SIZE(das16_boards), - .offset = sizeof(das16_boards[0]), -}; - #define DAS16_TIMEOUT 1000 /* Period for timer interrupt in jiffies. It's a function @@ -926,6 +556,62 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } +/* utility function that suggests a dma transfer size in bytes */ +static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, + struct comedi_cmd cmd) +{ + unsigned int size; + unsigned int freq; + + /* if we are using timer interrupt, we don't care how long it + * will take to complete transfer since it will be interrupted + * by timer interrupt */ + if (devpriv->timer_mode) + return DAS16_DMA_SIZE; + + /* otherwise, we are relying on dma terminal count interrupt, + * so pick a reasonable size */ + if (cmd.convert_src == TRIG_TIMER) + freq = 1000000000 / cmd.convert_arg; + else if (cmd.scan_begin_src == TRIG_TIMER) + freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len; + /* return some default value */ + else + freq = 0xffffffff; + + if (cmd.flags & TRIG_WAKE_EOS) { + size = sample_size * cmd.chanlist_len; + } else { + /* make buffer fill in no more than 1/3 second */ + size = (freq / 3) * sample_size; + } + + /* set a minimum and maximum size allowed */ + if (size > DAS16_DMA_SIZE) + size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size; + else if (size < sample_size) + size = sample_size; + + if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count) + size = devpriv->adc_byte_count; + + return size; +} + +static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, + int rounding_flags) +{ + i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), + &(devpriv->divisor2), &ns, + rounding_flags & TRIG_ROUND_MASK); + + /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ + i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2); + i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2); + + return ns; +} + static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_async *async = s->async; @@ -1170,34 +856,6 @@ static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -static irqreturn_t das16_dma_interrupt(int irq, void *d) -{ - int status; - struct comedi_device *dev = d; - - status = inb(dev->iobase + DAS16_STATUS); - - if ((status & DAS16_INT) == 0) { - DEBUG_PRINT("spurious interrupt\n"); - return IRQ_NONE; - } - - /* clear interrupt */ - outb(0x00, dev->iobase + DAS16_STATUS); - das16_interrupt(dev); - return IRQ_HANDLED; -} - -static void das16_timer_interrupt(unsigned long arg) -{ - struct comedi_device *dev = (struct comedi_device *)arg; - - das16_interrupt(dev); - - if (devpriv->timer_running) - mod_timer(&devpriv->timer, jiffies + timer_period()); -} - /* the pc104-das16jr (at least) has problems if the dma transfer is interrupted in the middle of transferring a 16 bit sample, so this function takes care to get @@ -1309,18 +967,32 @@ static void das16_interrupt(struct comedi_device *dev) cfc_handle_events(dev, s); } -static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, - int rounding_flags) +static irqreturn_t das16_dma_interrupt(int irq, void *d) { - i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), - &(devpriv->divisor2), &ns, - rounding_flags & TRIG_ROUND_MASK); + int status; + struct comedi_device *dev = d; - /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ - i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2); - i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2); + status = inb(dev->iobase + DAS16_STATUS); - return ns; + if ((status & DAS16_INT) == 0) { + DEBUG_PRINT("spurious interrupt\n"); + return IRQ_NONE; + } + + /* clear interrupt */ + outb(0x00, dev->iobase + DAS16_STATUS); + das16_interrupt(dev); + return IRQ_HANDLED; +} + +static void das16_timer_interrupt(unsigned long arg) +{ + struct comedi_device *dev = (struct comedi_device *)arg; + + das16_interrupt(dev); + + if (devpriv->timer_running) + mod_timer(&devpriv->timer, jiffies + timer_period()); } static void reg_dump(struct comedi_device *dev) @@ -1394,6 +1066,22 @@ static int das1600_mode_detect(struct comedi_device *dev) return 0; } +static void das16_ai_munge(struct comedi_device *dev, + struct comedi_subdevice *s, void *array, + unsigned int num_bytes, + unsigned int start_chan_index) +{ + unsigned int i, num_samples = num_bytes / sizeof(short); + short *data = array; + + for (i = 0; i < num_samples; i++) { + data[i] = le16_to_cpu(data[i]); + if (thisboard->ai_nbits == 12) + data[i] = (data[i] >> 4) & 0xfff; + + } +} + /* * * Options list: @@ -1402,7 +1090,6 @@ static int das1600_mode_detect(struct comedi_device *dev) * 2 DMA * 3 Clock speed (in MHz) */ - static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; @@ -1675,15 +1362,11 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int das16_detach(struct comedi_device *dev) +static void das16_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: das16: remove\n", dev->minor); - das16_reset(dev); - if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 4); - if (devpriv) { int i; for (i = 0; i < 2; i++) { @@ -1698,10 +1381,8 @@ static int das16_detach(struct comedi_device *dev) kfree(devpriv->user_ai_range_table); kfree(devpriv->user_ao_range_table); } - if (dev->irq) free_irq(dev->irq, dev); - if (dev->iobase) { if (thisboard->size < 0x400) { release_region(dev->iobase, thisboard->size); @@ -1711,80 +1392,318 @@ static int das16_detach(struct comedi_device *dev) thisboard->size & 0x3ff); } } - - return 0; } -static int __init driver_das16_init_module(void) -{ - return comedi_driver_register(&driver_das16); -} - -static void __exit driver_das16_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das16); -} - -module_init(driver_das16_init_module); -module_exit(driver_das16_cleanup_module); - -/* utility function that suggests a dma transfer size in bytes */ -static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, - struct comedi_cmd cmd) -{ - unsigned int size; - unsigned int freq; - - /* if we are using timer interrupt, we don't care how long it - * will take to complete transfer since it will be interrupted - * by timer interrupt */ - if (devpriv->timer_mode) - return DAS16_DMA_SIZE; - - /* otherwise, we are relying on dma terminal count interrupt, - * so pick a reasonable size */ - if (cmd.convert_src == TRIG_TIMER) - freq = 1000000000 / cmd.convert_arg; - else if (cmd.scan_begin_src == TRIG_TIMER) - freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len; - /* return some default value */ - else - freq = 0xffffffff; - - if (cmd.flags & TRIG_WAKE_EOS) { - size = sample_size * cmd.chanlist_len; - } else { - /* make buffer fill in no more than 1/3 second */ - size = (freq / 3) * sample_size; - } - - /* set a minimum and maximum size allowed */ - if (size > DAS16_DMA_SIZE) - size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size; - else if (size < sample_size) - size = sample_size; - - if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count) - size = devpriv->adc_byte_count; - - return size; -} - -static void das16_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *array, - unsigned int num_bytes, - unsigned int start_chan_index) -{ - unsigned int i, num_samples = num_bytes / sizeof(short); - short *data = array; - - for (i = 0; i < num_samples; i++) { - data[i] = le16_to_cpu(data[i]); - if (thisboard->ai_nbits == 12) - data[i] = (data[i] >> 4) & 0xfff; +static const struct das16_board das16_boards[] = { + { + .name = "das-16", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 15000, + .ai_pg = das16_pg_none, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x10, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0x00, + }, { + .name = "das-16g", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 15000, + .ai_pg = das16_pg_none, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x10, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0x00, + }, { + .name = "das-16f", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 8500, + .ai_pg = das16_pg_none, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x10, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0x00, + }, { + .name = "cio-das16", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 20000, + .ai_pg = das16_pg_none, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x10, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0x80, + }, { + .name = "cio-das16/f", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_none, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x10, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0x80, + }, { + .name = "cio-das16/jr", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 7692, + .ai_pg = das16_pg_16jr, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x10, + .id = 0x00, + }, { + .name = "pc104-das16jr", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 3300, + .ai_pg = das16_pg_16jr, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x10, + .id = 0x00, + }, { + .name = "cio-das16jr/16", + .ai = das16_ai_rinsn, + .ai_nbits = 16, + .ai_speed = 10000, + .ai_pg = das16_pg_16jr_16, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x10, + .id = 0x00, + }, { + .name = "pc104-das16jr/16", + .ai = das16_ai_rinsn, + .ai_nbits = 16, + .ai_speed = 10000, + .ai_pg = das16_pg_16jr_16, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x10, + .id = 0x00, + }, { + .name = "das-1201", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 20000, + .ai_pg = das16_pg_none, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0x20, + }, { + .name = "das-1202", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_none, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0x20, + }, { + .name = "das-1401", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_1601, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x0, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "das-1402", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_1602, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x0, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "das-1601", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_1601, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "das-1602", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_1602, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1401/12", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 6250, + .ai_pg = das16_pg_1601, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1402/12", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 6250, + .ai_pg = das16_pg_1602, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1402/16", + .ai = das16_ai_rinsn, + .ai_nbits = 16, + .ai_speed = 10000, + .ai_pg = das16_pg_1602, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1601/12", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 6250, + .ai_pg = das16_pg_1601, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1602/12", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 10000, + .ai_pg = das16_pg_1602, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das1602/16", + .ai = das16_ai_rinsn, + .ai_nbits = 16, + .ai_speed = 10000, + .ai_pg = das16_pg_1602, + .ao = das16_ao_winsn, + .ao_nbits = 12, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0x400, + .i8254_offset = 0x0c, + .size = 0x408, + .id = 0xc0, + }, { + .name = "cio-das16/330", + .ai = das16_ai_rinsn, + .ai_nbits = 12, + .ai_speed = 3030, + .ai_pg = das16_pg_16jr, + .ao = NULL, + .di = das16_di_rbits, + .do_ = das16_do_wbits, + .i8255_offset = 0, + .i8254_offset = 0x0c, + .size = 0x14, + .id = 0xf0, + }, +}; - } -} +static struct comedi_driver das16_driver = { + .driver_name = "das16", + .module = THIS_MODULE, + .attach = das16_attach, + .detach = das16_detach, + .board_name = &das16_boards[0].name, + .num_names = ARRAY_SIZE(das16_boards), + .offset = sizeof(das16_boards[0]), +}; +module_comedi_driver(das16_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 5376e71..d2e1490 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -132,57 +132,11 @@ static const struct comedi_lrange range_das16m1 = { 9, } }; -static int das16m1_do_wbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16m1_di_rbits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int das16m1_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int das16m1_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); -static int das16m1_cmd_exec(struct comedi_device *dev, - struct comedi_subdevice *s); -static int das16m1_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); - -static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s); -static irqreturn_t das16m1_interrupt(int irq, void *d); -static void das16m1_handler(struct comedi_device *dev, unsigned int status); - -static unsigned int das16m1_set_pacer(struct comedi_device *dev, - unsigned int ns, int round_flag); - -static int das16m1_irq_bits(unsigned int irq); - struct das16m1_board { const char *name; unsigned int ai_speed; }; -static const struct das16m1_board das16m1_boards[] = { - { - .name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */ - .ai_speed = 1000, /* 1MHz max speed */ - }, -}; - -static int das16m1_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int das16m1_detach(struct comedi_device *dev); -static struct comedi_driver driver_das16m1 = { - .driver_name = "das16m1", - .module = THIS_MODULE, - .attach = das16m1_attach, - .detach = das16m1_detach, - .board_name = &das16m1_boards[0].name, - .num_names = ARRAY_SIZE(das16m1_boards), - .offset = sizeof(das16m1_boards[0]), -}; - struct das16m1_private_struct { unsigned int control_state; volatile unsigned int adc_count; /* number of samples completed */ @@ -198,22 +152,17 @@ struct das16m1_private_struct { #define devpriv ((struct das16m1_private_struct *)(dev->private)) #define thisboard ((const struct das16m1_board *)(dev->board_ptr)) -static int __init driver_das16m1_init_module(void) +static inline short munge_sample(short data) { - return comedi_driver_register(&driver_das16m1); + return (data >> 4) & 0xfff; } -static void __exit driver_das16m1_cleanup_module(void) +static void munge_sample_array(short *array, unsigned int num_elements) { - comedi_driver_unregister(&driver_das16m1); -} - -module_init(driver_das16m1_init_module); -module_exit(driver_das16m1_cleanup_module); + unsigned int i; -static inline short munge_sample(short data) -{ - return (data >> 4) & 0xfff; + for (i = 0; i < num_elements; i++) + array[i] = munge_sample(array[i]); } static int das16m1_cmd_test(struct comedi_device *dev, @@ -340,6 +289,25 @@ static int das16m1_cmd_test(struct comedi_device *dev, return 0; } +/* This function takes a time in nanoseconds and sets the * + * 2 pacer clocks to the closest frequency possible. It also * + * returns the actual sampling period. */ +static unsigned int das16m1_set_pacer(struct comedi_device *dev, + unsigned int ns, int rounding_flags) +{ + i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1), + &(devpriv->divisor2), &ns, + rounding_flags & TRIG_ROUND_MASK); + + /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ + i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1, + 2); + i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2, + 2); + + return ns; +} + static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -484,57 +452,6 @@ static int das16m1_do_wbits(struct comedi_device *dev, return 2; } -static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s) -{ - unsigned long flags; - unsigned int status; - - /* prevent race with interrupt handler */ - spin_lock_irqsave(&dev->spinlock, flags); - status = inb(dev->iobase + DAS16M1_CS); - das16m1_handler(dev, status); - spin_unlock_irqrestore(&dev->spinlock, flags); - - return s->async->buf_write_count - s->async->buf_read_count; -} - -static irqreturn_t das16m1_interrupt(int irq, void *d) -{ - int status; - struct comedi_device *dev = d; - - if (dev->attached == 0) { - comedi_error(dev, "premature interrupt"); - return IRQ_HANDLED; - } - /* prevent race with comedi_poll() */ - spin_lock(&dev->spinlock); - - status = inb(dev->iobase + DAS16M1_CS); - - if ((status & (IRQDATA | OVRUN)) == 0) { - comedi_error(dev, "spurious interrupt"); - spin_unlock(&dev->spinlock); - return IRQ_NONE; - } - - das16m1_handler(dev, status); - - /* clear interrupt */ - outb(0, dev->iobase + DAS16M1_CLEAR_INTR); - - spin_unlock(&dev->spinlock); - return IRQ_HANDLED; -} - -static void munge_sample_array(short *array, unsigned int num_elements) -{ - unsigned int i; - - for (i = 0; i < num_elements; i++) - array[i] = munge_sample(array[i]); -} - static void das16m1_handler(struct comedi_device *dev, unsigned int status) { struct comedi_subdevice *s; @@ -596,23 +513,47 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status) } -/* This function takes a time in nanoseconds and sets the * - * 2 pacer clocks to the closest frequency possible. It also * - * returns the actual sampling period. */ -static unsigned int das16m1_set_pacer(struct comedi_device *dev, - unsigned int ns, int rounding_flags) +static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s) { - i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1), - &(devpriv->divisor2), &ns, - rounding_flags & TRIG_ROUND_MASK); + unsigned long flags; + unsigned int status; - /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ - i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1, - 2); - i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2, - 2); + /* prevent race with interrupt handler */ + spin_lock_irqsave(&dev->spinlock, flags); + status = inb(dev->iobase + DAS16M1_CS); + das16m1_handler(dev, status); + spin_unlock_irqrestore(&dev->spinlock, flags); - return ns; + return s->async->buf_write_count - s->async->buf_read_count; +} + +static irqreturn_t das16m1_interrupt(int irq, void *d) +{ + int status; + struct comedi_device *dev = d; + + if (dev->attached == 0) { + comedi_error(dev, "premature interrupt"); + return IRQ_HANDLED; + } + /* prevent race with comedi_poll() */ + spin_lock(&dev->spinlock); + + status = inb(dev->iobase + DAS16M1_CS); + + if ((status & (IRQDATA | OVRUN)) == 0) { + comedi_error(dev, "spurious interrupt"); + spin_unlock(&dev->spinlock); + return IRQ_NONE; + } + + das16m1_handler(dev, status); + + /* clear interrupt */ + outb(0, dev->iobase + DAS16M1_CLEAR_INTR); + + spin_unlock(&dev->spinlock); + return IRQ_HANDLED; } static int das16m1_irq_bits(unsigned int irq) @@ -656,7 +597,6 @@ static int das16m1_irq_bits(unsigned int irq) * 0 I/O base * 1 IRQ */ - static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -673,12 +613,12 @@ static int das16m1_attach(struct comedi_device *dev, dev->board_name = thisboard->name; - if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) { + if (!request_region(iobase, DAS16M1_SIZE, dev->driver->driver_name)) { comedi_error(dev, "I/O port conflict\n"); return -EIO; } if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2, - driver_das16m1.driver_name)) { + dev->driver->driver_name)) { release_region(iobase, DAS16M1_SIZE); comedi_error(dev, "I/O port conflict\n"); return -EIO; @@ -690,7 +630,7 @@ static int das16m1_attach(struct comedi_device *dev, /* make sure it is valid */ if (das16m1_irq_bits(irq) >= 0) { ret = request_irq(irq, das16m1_interrupt, 0, - driver_das16m1.driver_name, dev); + dev->driver->driver_name, dev); if (ret < 0) return ret; dev->irq = irq; @@ -763,25 +703,36 @@ static int das16m1_attach(struct comedi_device *dev, return 0; } -static int das16m1_detach(struct comedi_device *dev) +static void das16m1_detach(struct comedi_device *dev) { - -/* das16m1_reset(dev); */ - if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 3); - if (dev->irq) free_irq(dev->irq, dev); - if (dev->iobase) { release_region(dev->iobase, DAS16M1_SIZE); release_region(dev->iobase + DAS16M1_82C55, DAS16M1_SIZE2); } - - return 0; } +static const struct das16m1_board das16m1_boards[] = { + { + .name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */ + .ai_speed = 1000, /* 1MHz max speed */ + }, +}; + +static struct comedi_driver das16m1_driver = { + .driver_name = "das16m1", + .module = THIS_MODULE, + .attach = das16m1_attach, + .detach = das16m1_detach, + .board_name = &das16m1_boards[0].name, + .num_names = ARRAY_SIZE(das16m1_boards), + .offset = sizeof(das16m1_boards[0]), +}; +module_comedi_driver(das16m1_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 99ada5a..2ac3443 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -183,9 +183,6 @@ enum { das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao }; -static int das1800_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int das1800_detach(struct comedi_device *dev); static int das1800_probe(struct comedi_device *dev); static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s); @@ -518,33 +515,6 @@ static const struct comedi_lrange range_ao_2 = { }; */ -static struct comedi_driver driver_das1800 = { - .driver_name = "das1800", - .module = THIS_MODULE, - .attach = das1800_attach, - .detach = das1800_detach, - .num_names = ARRAY_SIZE(das1800_boards), - .board_name = &das1800_boards[0].name, - .offset = sizeof(struct das1800_board), -}; - -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __init driver_das1800_init_module(void) -{ - return comedi_driver_register(&driver_das1800); -} - -static void __exit driver_das1800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das1800); -} - -module_init(driver_das1800_init_module); -module_exit(driver_das1800_cleanup_module); - static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, unsigned int dma1) { @@ -579,7 +549,7 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, return -EINVAL; break; } - if (request_dma(dma0, driver_das1800.driver_name)) { + if (request_dma(dma0, dev->driver->driver_name)) { dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", dma0); return -EINVAL; @@ -587,7 +557,7 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, devpriv->dma0 = dma0; devpriv->dma_current = dma0; if (dma1) { - if (request_dma(dma1, driver_das1800.driver_name)) { + if (request_dma(dma1, dev->driver->driver_name)) { dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", dma1); return -EINVAL; @@ -633,7 +603,7 @@ static int das1800_attach(struct comedi_device *dev, return -ENOMEM; printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, - driver_das1800.driver_name, iobase); + dev->driver->driver_name, iobase); if (irq) { printk(KERN_CONT ", irq %u", irq); if (dma0) { @@ -650,7 +620,7 @@ static int das1800_attach(struct comedi_device *dev, } /* check if io addresses are available */ - if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { + if (!request_region(iobase, DAS1800_SIZE, dev->driver->driver_name)) { printk (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1); @@ -671,7 +641,7 @@ static int das1800_attach(struct comedi_device *dev, if (thisboard->ao_ability == 2) { iobase2 = iobase + IOBASE2; if (!request_region(iobase2, DAS1800_SIZE, - driver_das1800.driver_name)) { + dev->driver->driver_name)) { printk (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1); @@ -683,7 +653,7 @@ static int das1800_attach(struct comedi_device *dev, /* grab our IRQ */ if (irq) { if (request_irq(irq, das1800_interrupt, 0, - driver_das1800.driver_name, dev)) { + dev->driver->driver_name, dev)) { dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", irq); return -EINVAL; @@ -797,9 +767,8 @@ static int das1800_attach(struct comedi_device *dev, return 0; }; -static int das1800_detach(struct comedi_device *dev) +static void das1800_detach(struct comedi_device *dev) { - /* only free stuff if it has been allocated by _attach */ if (dev->iobase) release_region(dev->iobase, DAS1800_SIZE); if (dev->irq) @@ -814,11 +783,6 @@ static int das1800_detach(struct comedi_device *dev) kfree(devpriv->ai_buf0); kfree(devpriv->ai_buf1); } - - dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor, - driver_das1800.driver_name); - - return 0; }; /* probes and checks das-1800 series board type @@ -1811,6 +1775,17 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) return size; } +static struct comedi_driver das1800_driver = { + .driver_name = "das1800", + .module = THIS_MODULE, + .attach = das1800_attach, + .detach = das1800_detach, + .num_names = ARRAY_SIZE(das1800_boards), + .board_name = &das1800_boards[0].name, + .offset = sizeof(struct das1800_board), +}; +module_comedi_driver(das1800_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index f2568414..881f392 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -99,29 +99,6 @@ This driver has suffered bitrot. #define C2 0x80 #define RWLH 0x30 -static int das6402_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int das6402_detach(struct comedi_device *dev); -static struct comedi_driver driver_das6402 = { - .driver_name = "das6402", - .module = THIS_MODULE, - .attach = das6402_attach, - .detach = das6402_detach, -}; - -static int __init driver_das6402_init_module(void) -{ - return comedi_driver_register(&driver_das6402); -} - -static void __exit driver_das6402_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das6402); -} - -module_init(driver_das6402_init_module); -module_exit(driver_das6402_cleanup_module); - struct das6402_private { int ai_bytes_to_read; @@ -130,7 +107,14 @@ struct das6402_private { #define devpriv ((struct das6402_private *)dev->private) static void das6402_ai_fifo_dregs(struct comedi_device *dev, - struct comedi_subdevice *s); + struct comedi_subdevice *s) +{ + while (1) { + if (!(inb(dev->iobase + 8) & 0x01)) + return; + comedi_buf_put(s->async, inw(dev->iobase)); + } +} static void das6402_setcounter(struct comedi_device *dev) { @@ -209,16 +193,6 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n) } #endif -static void das6402_ai_fifo_dregs(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - while (1) { - if (!(inb(dev->iobase + 8) & 0x01)) - return; - comedi_buf_put(s->async, inw(dev->iobase)); - } -} - static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -300,16 +274,6 @@ static int board_init(struct comedi_device *dev) return 0; } -static int das6402_detach(struct comedi_device *dev) -{ - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->iobase) - release_region(dev->iobase, DAS6402_SIZE); - - return 0; -} - static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -363,6 +327,22 @@ static int das6402_attach(struct comedi_device *dev, return 0; } +static void das6402_detach(struct comedi_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->iobase) + release_region(dev->iobase, DAS6402_SIZE); +} + +static struct comedi_driver das6402_driver = { + .driver_name = "das6402", + .module = THIS_MODULE, + .attach = das6402_attach, + .detach = das6402_detach, +}; +module_comedi_driver(das6402_driver) + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 6e347b4..a3a54e1 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -245,7 +245,7 @@ struct das800_private { static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int das800_detach(struct comedi_device *dev); +static void das800_detach(struct comedi_device *dev); static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static struct comedi_driver driver_das800 = { @@ -556,16 +556,12 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; }; -static int das800_detach(struct comedi_device *dev) +static void das800_detach(struct comedi_device *dev) { - dev_info(dev->hw_dev, "comedi%d: das800: remove\n", dev->minor); - - /* only free stuff if it has been allocated by _attach */ if (dev->iobase) release_region(dev->iobase, DAS800_SIZE); if (dev->irq) free_irq(dev->irq, dev); - return 0; }; static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 2b4e6e6..8382890 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -224,7 +224,7 @@ struct dmm32at_private { */ static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dmm32at_detach(struct comedi_device *dev); +static void dmm32at_detach(struct comedi_device *dev); static struct comedi_driver driver_dmm32at = { .driver_name = "dmm32at", .module = THIS_MODULE, @@ -450,23 +450,12 @@ static int dmm32at_attach(struct comedi_device *dev, } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int dmm32at_detach(struct comedi_device *dev) +static void dmm32at_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: dmm32at: remove\n", dev->minor); if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) release_region(dev->iobase, DMM32AT_MEMSIZE); - - return 0; } /* diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index b85c836..625bd61 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -88,29 +88,6 @@ Configuration options: #define DT2801_STATUS 1 #define DT2801_CMD 1 -static int dt2801_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2801_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2801 = { - .driver_name = "dt2801", - .module = THIS_MODULE, - .attach = dt2801_attach, - .detach = dt2801_detach, -}; - -static int __init driver_dt2801_init_module(void) -{ - return comedi_driver_register(&driver_dt2801); -} - -static void __exit driver_dt2801_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2801); -} - -module_init(driver_dt2801_init_module); -module_exit(driver_dt2801_cleanup_module); - #if 0 /* ignore 'defined but not used' warning */ static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, { @@ -258,22 +235,6 @@ struct dt2801_private { #define devpriv ((struct dt2801_private *)dev->private) -static int dt2801_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2801_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2801_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2801_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2801_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /* These are the low-level routines: writecommand: write a command to the board writedata: write data byte @@ -503,6 +464,123 @@ static const struct comedi_lrange *ai_range_lkup(int type, int opt) return &range_unknown; } +static int dt2801_error(struct comedi_device *dev, int stat) +{ + if (stat < 0) { + if (stat == -ETIME) + printk("dt2801: timeout\n"); + else + printk("dt2801: error %d\n", stat); + return stat; + } + printk("dt2801: error status 0x%02x, resetting...\n", stat); + + dt2801_reset(dev); + dt2801_reset(dev); + + return -EIO; +} + +static int dt2801_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int d; + int stat; + int i; + + for (i = 0; i < insn->n; i++) { + stat = dt2801_writecmd(dev, DT_C_READ_ADIM); + dt2801_writedata(dev, CR_RANGE(insn->chanspec)); + dt2801_writedata(dev, CR_CHAN(insn->chanspec)); + stat = dt2801_readdata2(dev, &d); + + if (stat != 0) + return dt2801_error(dev, stat); + + data[i] = d; + } + + return i; +} + +static int dt2801_ao_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; + + return 1; +} + +static int dt2801_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + dt2801_writecmd(dev, DT_C_WRITE_DAIM); + dt2801_writedata(dev, CR_CHAN(insn->chanspec)); + dt2801_writedata2(dev, data[0]); + + devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0]; + + return 1; +} + +static int dt2801_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int which = 0; + + if (s == dev->subdevices + 4) + which = 1; + + if (insn->n != 2) + return -EINVAL; + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + dt2801_writecmd(dev, DT_C_WRITE_DIG); + dt2801_writedata(dev, which); + dt2801_writedata(dev, s->state); + } + dt2801_writecmd(dev, DT_C_READ_DIG); + dt2801_writedata(dev, which); + dt2801_readdata(dev, data + 1); + + return 2; +} + +static int dt2801_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int which = 0; + + if (s == dev->subdevices + 4) + which = 1; + + /* configure */ + switch (data[0]) { + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits = 0xff; + dt2801_writecmd(dev, DT_C_SET_DIGOUT); + break; + case INSN_CONFIG_DIO_INPUT: + s->io_bits = 0; + dt2801_writecmd(dev, DT_C_SET_DIGIN); + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + default: + return -EINVAL; + } + dt2801_writedata(dev, which); + + return 1; +} + /* options: [0] - i/o base @@ -615,130 +693,19 @@ out: return ret; } -static int dt2801_detach(struct comedi_device *dev) +static void dt2801_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, DT2801_IOSIZE); - - return 0; -} - -static int dt2801_error(struct comedi_device *dev, int stat) -{ - if (stat < 0) { - if (stat == -ETIME) - printk("dt2801: timeout\n"); - else - printk("dt2801: error %d\n", stat); - return stat; - } - printk("dt2801: error status 0x%02x, resetting...\n", stat); - - dt2801_reset(dev); - dt2801_reset(dev); - - return -EIO; -} - -static int dt2801_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int d; - int stat; - int i; - - for (i = 0; i < insn->n; i++) { - stat = dt2801_writecmd(dev, DT_C_READ_ADIM); - dt2801_writedata(dev, CR_RANGE(insn->chanspec)); - dt2801_writedata(dev, CR_CHAN(insn->chanspec)); - stat = dt2801_readdata2(dev, &d); - - if (stat != 0) - return dt2801_error(dev, stat); - - data[i] = d; - } - - return i; -} - -static int dt2801_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; - - return 1; -} - -static int dt2801_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - dt2801_writecmd(dev, DT_C_WRITE_DAIM); - dt2801_writedata(dev, CR_CHAN(insn->chanspec)); - dt2801_writedata2(dev, data[0]); - - devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0]; - - return 1; -} - -static int dt2801_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int which = 0; - - if (s == dev->subdevices + 4) - which = 1; - - if (insn->n != 2) - return -EINVAL; - if (data[0]) { - s->state &= ~data[0]; - s->state |= (data[0] & data[1]); - dt2801_writecmd(dev, DT_C_WRITE_DIG); - dt2801_writedata(dev, which); - dt2801_writedata(dev, s->state); - } - dt2801_writecmd(dev, DT_C_READ_DIG); - dt2801_writedata(dev, which); - dt2801_readdata(dev, data + 1); - - return 2; } -static int dt2801_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int which = 0; - - if (s == dev->subdevices + 4) - which = 1; - - /* configure */ - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits = 0xff; - dt2801_writecmd(dev, DT_C_SET_DIGOUT); - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits = 0; - dt2801_writecmd(dev, DT_C_SET_DIGIN); - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - default: - return -EINVAL; - } - dt2801_writedata(dev, which); - - return 1; -} +static struct comedi_driver dt2801_driver = { + .driver_name = "dt2801", + .module = THIS_MODULE, + .attach = dt2801_attach, + .detach = dt2801_detach, +}; +module_comedi_driver(dt2801_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 0131d52..106ffea 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -211,61 +211,8 @@ struct dt2811_board { const struct comedi_lrange *unip_5; }; -static const struct dt2811_board boardtypes[] = { - {"dt2811-pgh", - &range_dt2811_pgh_ai_5_bipolar, - &range_dt2811_pgh_ai_2_5_bipolar, - &range_dt2811_pgh_ai_5_unipolar, - }, - {"dt2811-pgl", - &range_dt2811_pgl_ai_5_bipolar, - &range_dt2811_pgl_ai_2_5_bipolar, - &range_dt2811_pgl_ai_5_unipolar, - }, -}; - #define this_board ((const struct dt2811_board *)dev->board_ptr) -static int dt2811_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2811_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2811 = { - .driver_name = "dt2811", - .module = THIS_MODULE, - .attach = dt2811_attach, - .detach = dt2811_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct dt2811_board), -}; - -static int __init driver_dt2811_init_module(void) -{ - return comedi_driver_register(&driver_dt2811); -} - -static void __exit driver_dt2811_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2811); -} - -module_init(driver_dt2811_init_module); -module_exit(driver_dt2811_cleanup_module); - -static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2811_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2811_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dt2811_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - enum { card_2811_pgh, card_2811_pgl }; struct dt2811_private { @@ -317,6 +264,120 @@ static irqreturn_t dt2811_interrupt(int irq, void *d) } #endif +static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int chan = CR_CHAN(insn->chanspec); + int timeout = DT2811_TIMEOUT; + int i; + + for (i = 0; i < insn->n; i++) { + outb(chan, dev->iobase + DT2811_ADGCR); + + while (timeout + && inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY) + timeout--; + if (!timeout) + return -ETIME; + + data[i] = inb(dev->iobase + DT2811_ADDATLO); + data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8; + data[i] &= 0xfff; + } + + return i; +} + +#if 0 +/* Wow. This is code from the Comedi stone age. But it hasn't been + * replaced, so I'll let it stay. */ +int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) +{ + struct comedi_device *dev = comedi_devices + minor; + + if (adtrig->n < 1) + return 0; + dev->curadchan = adtrig->chan; + switch (dev->i_admode) { + case COMEDI_MDEMAND: + dev->ntrig = adtrig->n - 1; + /* not necessary */ + /*printk("dt2811: AD soft trigger\n"); */ + /*outb(DT2811_CLRERROR|DT2811_INTENB, + dev->iobase+DT2811_ADCSR); */ + outb(dev->curadchan, dev->iobase + DT2811_ADGCR); + do_gettimeofday(&trigtime); + break; + case COMEDI_MCONTS: + dev->ntrig = adtrig->n; + break; + } + + return 0; +} +#endif + +static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i; + int chan; + + chan = CR_CHAN(insn->chanspec); + + for (i = 0; i < insn->n; i++) { + outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan); + outb((data[i] >> 8) & 0xff, + dev->iobase + DT2811_DADAT0HI + 2 * chan); + devpriv->ao_readback[chan] = data[i]; + } + + return i; +} + +static int dt2811_ao_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i; + int chan; + + chan = CR_CHAN(insn->chanspec); + + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_readback[chan]; + + return i; +} + +static int dt2811_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + data[1] = inb(dev->iobase + DT2811_DIO); + + return 2; +} + +static int dt2811_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + outb(s->state, dev->iobase + DT2811_DIO); + + data[1] = s->state; + + return 2; +} + /* options[0] Board base address options[1] IRQ @@ -337,7 +398,6 @@ static irqreturn_t dt2811_interrupt(int irq, void *d) 1 == bipolar 2.5V (-2.5V -- +2.5V) 2 == unipolar 5V (0V -- +5V) */ - static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) { /* int i, irq; */ @@ -511,131 +571,38 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int dt2811_detach(struct comedi_device *dev) +static void dt2811_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: dt2811: remove\n", dev->minor); - if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) release_region(dev->iobase, DT2811_SIZE); - - return 0; -} - -static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int chan = CR_CHAN(insn->chanspec); - int timeout = DT2811_TIMEOUT; - int i; - - for (i = 0; i < insn->n; i++) { - outb(chan, dev->iobase + DT2811_ADGCR); - - while (timeout - && inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY) - timeout--; - if (!timeout) - return -ETIME; - - data[i] = inb(dev->iobase + DT2811_ADDATLO); - data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8; - data[i] &= 0xfff; - } - - return i; } -#if 0 -/* Wow. This is code from the Comedi stone age. But it hasn't been - * replaced, so I'll let it stay. */ -int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) -{ - struct comedi_device *dev = comedi_devices + minor; - - if (adtrig->n < 1) - return 0; - dev->curadchan = adtrig->chan; - switch (dev->i_admode) { - case COMEDI_MDEMAND: - dev->ntrig = adtrig->n - 1; - /* not necessary */ - /*printk("dt2811: AD soft trigger\n"); */ - /*outb(DT2811_CLRERROR|DT2811_INTENB, - dev->iobase+DT2811_ADCSR); */ - outb(dev->curadchan, dev->iobase + DT2811_ADGCR); - do_gettimeofday(&trigtime); - break; - case COMEDI_MCONTS: - dev->ntrig = adtrig->n; - break; - } - - return 0; -} -#endif - -static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int i; - int chan; - - chan = CR_CHAN(insn->chanspec); - - for (i = 0; i < insn->n; i++) { - outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan); - outb((data[i] >> 8) & 0xff, - dev->iobase + DT2811_DADAT0HI + 2 * chan); - devpriv->ao_readback[chan] = data[i]; - } - - return i; -} - -static int dt2811_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int i; - int chan; - - chan = CR_CHAN(insn->chanspec); - - for (i = 0; i < insn->n; i++) - data[i] = devpriv->ao_readback[chan]; - - return i; -} - -static int dt2811_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - data[1] = inb(dev->iobase + DT2811_DIO); - - return 2; -} - -static int dt2811_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - if (insn->n != 2) - return -EINVAL; - - s->state &= ~data[0]; - s->state |= data[0] & data[1]; - outb(s->state, dev->iobase + DT2811_DIO); - - data[1] = s->state; +static const struct dt2811_board boardtypes[] = { + { + .name = "dt2811-pgh", + .bip_5 = &range_dt2811_pgh_ai_5_bipolar, + .bip_2_5 = &range_dt2811_pgh_ai_2_5_bipolar, + .unip_5 = &range_dt2811_pgh_ai_5_unipolar, + }, { + .name = "dt2811-pgl", + .bip_5 = &range_dt2811_pgl_ai_5_bipolar, + .bip_2_5 = &range_dt2811_pgl_ai_2_5_bipolar, + .unip_5 = &range_dt2811_pgl_ai_5_unipolar, + }, +}; - return 2; -} +static struct comedi_driver dt2811_driver = { + .driver_name = "dt2811", + .module = THIS_MODULE, + .attach = dt2811_attach, + .detach = dt2811_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct dt2811_board), +}; +module_comedi_driver(dt2811_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 1c6248c..fa4ade6 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -60,31 +60,6 @@ addition, the clock does not seem to be very accurate. #define DT2814_ENB 0x10 #define DT2814_CHANMASK 0x0f -static int dt2814_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2814_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2814 = { - .driver_name = "dt2814", - .module = THIS_MODULE, - .attach = dt2814_attach, - .detach = dt2814_detach, -}; - -static int __init driver_dt2814_init_module(void) -{ - return comedi_driver_register(&driver_dt2814); -} - -static void __exit driver_dt2814_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2814); -} - -module_init(driver_dt2814_init_module); -module_exit(driver_dt2814_cleanup_module); - -static irqreturn_t dt2814_interrupt(int irq, void *dev); - struct dt2814_private { int ntrig; @@ -260,6 +235,45 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } +static irqreturn_t dt2814_interrupt(int irq, void *d) +{ + int lo, hi; + struct comedi_device *dev = d; + struct comedi_subdevice *s; + int data; + + if (!dev->attached) { + comedi_error(dev, "spurious interrupt"); + return IRQ_HANDLED; + } + + s = dev->subdevices + 0; + + hi = inb(dev->iobase + DT2814_DATA); + lo = inb(dev->iobase + DT2814_DATA); + + data = (hi << 4) | (lo >> 4); + + if (!(--devpriv->ntrig)) { + int i; + + outb(0, dev->iobase + DT2814_CSR); + /* note: turning off timed mode triggers another + sample. */ + + for (i = 0; i < DT2814_TIMEOUT; i++) { + if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH) + break; + } + inb(dev->iobase + DT2814_DATA); + inb(dev->iobase + DT2814_DATA); + + s->async->events |= COMEDI_CB_EOA; + } + comedi_event(dev, s); + return IRQ_HANDLED; +} + static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int i, irq; @@ -347,57 +361,21 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int dt2814_detach(struct comedi_device *dev) +static void dt2814_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: dt2814: remove\n", dev->minor); - if (dev->irq) free_irq(dev->irq, dev); - if (dev->iobase) release_region(dev->iobase, DT2814_SIZE); - - return 0; } -static irqreturn_t dt2814_interrupt(int irq, void *d) -{ - int lo, hi; - struct comedi_device *dev = d; - struct comedi_subdevice *s; - int data; - - if (!dev->attached) { - comedi_error(dev, "spurious interrupt"); - return IRQ_HANDLED; - } - - s = dev->subdevices + 0; - - hi = inb(dev->iobase + DT2814_DATA); - lo = inb(dev->iobase + DT2814_DATA); - - data = (hi << 4) | (lo >> 4); - - if (!(--devpriv->ntrig)) { - int i; - - outb(0, dev->iobase + DT2814_CSR); - /* note: turning off timed mode triggers another - sample. */ - - for (i = 0; i < DT2814_TIMEOUT; i++) { - if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH) - break; - } - inb(dev->iobase + DT2814_DATA); - inb(dev->iobase + DT2814_DATA); - - s->async->events |= COMEDI_CB_EOA; - } - comedi_event(dev, s); - return IRQ_HANDLED; -} +static struct comedi_driver dt2814_driver = { + .driver_name = "dt2814", + .module = THIS_MODULE, + .attach = dt2814_attach, + .detach = dt2814_detach, +}; +module_comedi_driver(dt2814_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 4155da4..bbab712 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -72,31 +72,6 @@ static const struct comedi_lrange #define DT2815_DATA 0 #define DT2815_STATUS 1 -static int dt2815_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2815_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2815 = { - .driver_name = "dt2815", - .module = THIS_MODULE, - .attach = dt2815_attach, - .detach = dt2815_detach, -}; - -static int __init driver_dt2815_init_module(void) -{ - return comedi_driver_register(&driver_dt2815); -} - -static void __exit driver_dt2815_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2815); -} - -module_init(driver_dt2815_init_module); -module_exit(driver_dt2815_cleanup_module); - -static void dt2815_free_resources(struct comedi_device *dev); - struct dt2815_private { const struct comedi_lrange *range_type_list[8]; @@ -252,20 +227,19 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static void dt2815_free_resources(struct comedi_device *dev) +static void dt2815_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, DT2815_SIZE); } -static int dt2815_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: dt2815: remove\n", dev->minor); - - dt2815_free_resources(dev); - - return 0; -} +static struct comedi_driver dt2815_driver = { + .driver_name = "dt2815", + .module = THIS_MODULE, + .attach = dt2815_attach, + .detach = dt2815_detach, +}; +module_comedi_driver(dt2815_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 99c1584..1ee10e7b 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -47,29 +47,6 @@ Configuration options: #define DT2817_CR 0 #define DT2817_DATA 1 -static int dt2817_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt2817_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt2817 = { - .driver_name = "dt2817", - .module = THIS_MODULE, - .attach = dt2817_attach, - .detach = dt2817_detach, -}; - -static int __init driver_dt2817_init_module(void) -{ - return comedi_driver_register(&driver_dt2817); -} - -static void __exit driver_dt2817_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt2817); -} - -module_init(driver_dt2817_init_module); -module_exit(driver_dt2817_cleanup_module); - static int dt2817_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -182,16 +159,20 @@ static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int dt2817_detach(struct comedi_device *dev) +static void dt2817_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: dt2817: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, DT2817_SIZE); - - return 0; } +static struct comedi_driver dt2817_driver = { + .driver_name = "dt2817", + .module = THIS_MODULE, + .attach = dt2817_attach, + .detach = dt2817_detach, +}; +module_comedi_driver(dt2817_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 95ebc26..736d8fa 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -221,136 +221,6 @@ struct dt282x_board { int dabits; }; -static const struct dt282x_board boardtypes[] = { - {.name = "dt2821", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2821-f", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 6500, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2821-g", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 4000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2823", - .adbits = 16, - .adchan_se = 0, - .adchan_di = 4, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 16, - }, - {.name = "dt2824-pgh", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt2824-pgl", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 1, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt2825", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 20000, - .ispgl = 1, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2827", - .adbits = 16, - .adchan_se = 0, - .adchan_di = 4, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2828", - .adbits = 12, - .adchan_se = 4, - .adchan_di = 0, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt2829", - .adbits = 16, - .adchan_se = 8, - .adchan_di = 0, - .ai_speed = 33250, - .ispgl = 0, - .dachan = 2, - .dabits = 16, - }, - {.name = "dt21-ez", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt23-ez", - .adbits = 16, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt24-ez", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 0, - .dachan = 0, - .dabits = 0, - }, - {.name = "dt24-ez-pgl", - .adbits = 12, - .adchan_se = 16, - .adchan_di = 8, - .ai_speed = 10000, - .ispgl = 1, - .dachan = 0, - .dabits = 0, - }, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dt282x_board)) #define this_board ((const struct dt282x_board *)dev->board_ptr) struct dt282x_private { @@ -411,33 +281,6 @@ struct dt282x_private { b \ } while (0) -static int dt282x_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt282x_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt282x = { - .driver_name = "dt282x", - .module = THIS_MODULE, - .attach = dt282x_attach, - .detach = dt282x_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct dt282x_board), -}; - -static int __init driver_dt282x_init_module(void) -{ - return comedi_driver_register(&driver_dt282x); -} - -static void __exit driver_dt282x_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dt282x); -} - -module_init(driver_dt282x_init_module); -module_exit(driver_dt282x_cleanup_module); - -static void free_resources(struct comedi_device *dev); static int prep_ai_dma(struct comedi_device *dev, int chan, int size); static int prep_ao_dma(struct comedi_device *dev, int chan, int size); static int dt282x_ai_cancel(struct comedi_device *dev, @@ -1271,6 +1114,52 @@ enum { /* i/o base, irq, dma channels */ opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */ }; +static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) +{ + int ret; + + devpriv->usedma = 0; + + if (!dma1 && !dma2) { + printk(KERN_ERR " (no dma)"); + return 0; + } + + if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) + return -EINVAL; + + if (dma2 < dma1) { + int i; + i = dma1; + dma1 = dma2; + dma2 = i; + } + + ret = request_dma(dma1, "dt282x A"); + if (ret) + return -EBUSY; + devpriv->dma[0].chan = dma1; + + ret = request_dma(dma2, "dt282x B"); + if (ret) + return -EBUSY; + devpriv->dma[1].chan = dma2; + + devpriv->dma_maxsize = PAGE_SIZE; + devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); + if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { + printk(KERN_ERR " can't get DMA memory"); + return -ENOMEM; + } + + printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); + + devpriv->usedma = 1; + + return 0; +} + /* options: 0 i/o base @@ -1442,7 +1331,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static void free_resources(struct comedi_device *dev) +static void dt282x_detach(struct comedi_device *dev) { if (dev->irq) free_irq(dev->irq, dev); @@ -1460,60 +1349,146 @@ static void free_resources(struct comedi_device *dev) } } -static int dt282x_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: dt282x: remove\n", dev->minor); - - free_resources(dev); - - return 0; -} - -static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) -{ - int ret; - - devpriv->usedma = 0; - - if (!dma1 && !dma2) { - printk(KERN_ERR " (no dma)"); - return 0; - } - - if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) - return -EINVAL; - - if (dma2 < dma1) { - int i; - i = dma1; - dma1 = dma2; - dma2 = i; - } - - ret = request_dma(dma1, "dt282x A"); - if (ret) - return -EBUSY; - devpriv->dma[0].chan = dma1; - - ret = request_dma(dma2, "dt282x B"); - if (ret) - return -EBUSY; - devpriv->dma[1].chan = dma2; - - devpriv->dma_maxsize = PAGE_SIZE; - devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { - printk(KERN_ERR " can't get DMA memory"); - return -ENOMEM; - } - - printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); - - devpriv->usedma = 1; +static const struct dt282x_board boardtypes[] = { + { + .name = "dt2821", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2821-f", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 6500, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2821-g", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 4000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2823", + .adbits = 16, + .adchan_se = 0, + .adchan_di = 4, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 16, + }, { + .name = "dt2824-pgh", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt2824-pgl", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 1, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt2825", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 20000, + .ispgl = 1, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2827", + .adbits = 16, + .adchan_se = 0, + .adchan_di = 4, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2828", + .adbits = 12, + .adchan_se = 4, + .adchan_di = 0, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt2829", + .adbits = 16, + .adchan_se = 8, + .adchan_di = 0, + .ai_speed = 33250, + .ispgl = 0, + .dachan = 2, + .dabits = 16, + }, { + .name = "dt21-ez", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt23-ez", + .adbits = 16, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt24-ez", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 0, + .dachan = 0, + .dabits = 0, + }, { + .name = "dt24-ez-pgl", + .adbits = 12, + .adchan_se = 16, + .adchan_di = 8, + .ai_speed = 10000, + .ispgl = 1, + .dachan = 0, + .dabits = 0, + }, +}; - return 0; -} +static struct comedi_driver dt282x_driver = { + .driver_name = "dt282x", + .module = THIS_MODULE, + .attach = dt282x_attach, + .detach = dt282x_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct dt282x_board), +}; +module_comedi_driver(dt282x_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 0a7979e..0d27326 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -164,19 +164,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { #define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype) #define this_board ((const struct dt3k_boardtype *)dev->board_ptr) -static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, dt3k_pci_table); - #define DT3000_SIZE (4*0x1000) /* dual-ported RAM location definitions */ @@ -276,54 +263,6 @@ struct dt3k_private { #define devpriv ((struct dt3k_private *)dev->private) -static int dt3000_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dt3000_detach(struct comedi_device *dev); -static struct comedi_driver driver_dt3000 = { - .driver_name = "dt3000", - .module = THIS_MODULE, - .attach = dt3000_attach, - .detach = dt3000_detach, -}; - -static int __devinit driver_dt3000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_dt3000.driver_name); -} - -static void __devexit driver_dt3000_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_dt3000_pci_driver = { - .id_table = dt3k_pci_table, - .probe = &driver_dt3000_pci_probe, - .remove = __devexit_p(&driver_dt3000_pci_remove) -}; - -static int __init driver_dt3000_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_dt3000); - if (retval < 0) - return retval; - - driver_dt3000_pci_driver.name = (char *)driver_dt3000.driver_name; - return pci_register_driver(&driver_dt3000_pci_driver); -} - -static void __exit driver_dt3000_cleanup_module(void) -{ - pci_unregister_driver(&driver_dt3000_pci_driver); - comedi_driver_unregister(&driver_dt3000); -} - -module_init(driver_dt3000_init_module); -module_exit(driver_dt3000_cleanup_module); - static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s); static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg, @@ -841,7 +780,77 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, return i; } -static int dt_pci_probe(struct comedi_device *dev, int bus, int slot); +static int setup_pci(struct comedi_device *dev) +{ + resource_size_t addr; + int ret; + + ret = comedi_pci_enable(devpriv->pci_dev, "dt3000"); + if (ret < 0) + return ret; + + addr = pci_resource_start(devpriv->pci_dev, 0); + devpriv->phys_addr = addr; + devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE); + if (!devpriv->io_addr) + return -ENOMEM; +#if DEBUG + printk("0x%08llx mapped to %p, ", + (unsigned long long)devpriv->phys_addr, devpriv->io_addr); +#endif + + return 0; +} + +static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board) +{ + int i; + + for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from); + from != NULL; + from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) { + for (i = 0; i < n_dt3k_boards; i++) { + if (from->device == dt3k_boardtypes[i].device_id) { + *board = i; + return from; + } + } + printk + ("unknown Data Translation PCI device found with device_id=0x%04x\n", + from->device); + } + *board = -1; + return from; +} + +static int dt_pci_probe(struct comedi_device *dev, int bus, int slot) +{ + int board; + int ret; + struct pci_dev *pcidev; + + pcidev = NULL; + while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) { + if ((bus == 0 && slot == 0) || + (pcidev->bus->number == bus && + PCI_SLOT(pcidev->devfn) == slot)) { + break; + } + } + devpriv->pci_dev = pcidev; + + if (board >= 0) + dev->board_ptr = dt3k_boardtypes + board; + + if (!devpriv->pci_dev) + return 0; + + ret = setup_pci(dev); + if (ret < 0) + return ret; + + return 1; +} static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -935,11 +944,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int dt3000_detach(struct comedi_device *dev) +static void dt3000_detach(struct comedi_device *dev) { if (dev->irq) free_irq(dev->irq, dev); - if (devpriv) { if (devpriv->pci_dev) { if (devpriv->phys_addr) @@ -949,85 +957,45 @@ static int dt3000_detach(struct comedi_device *dev) if (devpriv->io_addr) iounmap(devpriv->io_addr); } - /* XXX */ - - return 0; } -static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board); -static int setup_pci(struct comedi_device *dev); +static struct comedi_driver dt3000_driver = { + .driver_name = "dt3000", + .module = THIS_MODULE, + .attach = dt3000_attach, + .detach = dt3000_detach, +}; -static int dt_pci_probe(struct comedi_device *dev, int bus, int slot) +static int __devinit dt3000_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - int board; - int ret; - struct pci_dev *pcidev; - - pcidev = NULL; - while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) { - if ((bus == 0 && slot == 0) || - (pcidev->bus->number == bus && - PCI_SLOT(pcidev->devfn) == slot)) { - break; - } - } - devpriv->pci_dev = pcidev; - - if (board >= 0) - dev->board_ptr = dt3k_boardtypes + board; - - if (!devpriv->pci_dev) - return 0; - - ret = setup_pci(dev); - if (ret < 0) - return ret; - - return 1; + return comedi_pci_auto_config(dev, &dt3000_driver); } -static int setup_pci(struct comedi_device *dev) +static void __devexit dt3000_pci_remove(struct pci_dev *dev) { - resource_size_t addr; - int ret; - - ret = comedi_pci_enable(devpriv->pci_dev, "dt3000"); - if (ret < 0) - return ret; - - addr = pci_resource_start(devpriv->pci_dev, 0); - devpriv->phys_addr = addr; - devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE); - if (!devpriv->io_addr) - return -ENOMEM; -#if DEBUG - printk("0x%08llx mapped to %p, ", - (unsigned long long)devpriv->phys_addr, devpriv->io_addr); -#endif - - return 0; + comedi_pci_auto_unconfig(dev); } -static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board) -{ - int i; +static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, dt3000_pci_table); - for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from); - from != NULL; - from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) { - for (i = 0; i < n_dt3k_boards; i++) { - if (from->device == dt3k_boardtypes[i].device_id) { - *board = i; - return from; - } - } - printk - ("unknown Data Translation PCI device found with device_id=0x%04x\n", - from->device); - } - *board = -1; - return from; -} +static struct pci_driver dt3000_pci_driver = { + .name = "dt3000", + .id_table = dt3000_pci_table, + .probe = dt3000_pci_probe, + .remove = __devexit_p(dt3000_pci_remove), +}; +module_comedi_pci_driver(dt3000_driver, dt3000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 89a49dd..22cda5c 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -196,7 +196,7 @@ struct dt9812_flash_data { }; #define DT9812_MAX_NUM_MULTI_BYTE_RDS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8)) struct dt9812_read_multi { u8 count; @@ -209,8 +209,8 @@ struct dt9812_write_byte { }; #define DT9812_MAX_NUM_MULTI_BYTE_WRTS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ - sizeof(struct dt9812_write_byte)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ + sizeof(struct dt9812_write_byte)) struct dt9812_write_multi { u8 count; @@ -224,7 +224,8 @@ struct dt9812_rmw_byte { }; #define DT9812_MAX_NUM_MULTI_BYTE_RMWS \ - ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(struct dt9812_rmw_byte)) + ((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \ + sizeof(struct dt9812_rmw_byte)) struct dt9812_rmw_multi { u8 count; @@ -365,7 +366,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf, } static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count, - u8 * address, u8 * value) + u8 *address, u8 *value) { struct dt9812_usb_cmd cmd; int i, count, retval; @@ -391,8 +392,8 @@ static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count, } static int dt9812_write_multiple_registers(struct usb_dt9812 *dev, - int reg_count, u8 * address, - u8 * value) + int reg_count, u8 *address, + u8 *value) { struct dt9812_usb_cmd cmd; int i, count, retval; @@ -430,7 +431,7 @@ static int dt9812_rmw_multiple_registers(struct usb_dt9812 *dev, int reg_count, return retval; } -static int dt9812_digital_in(struct slot_dt9812 *slot, u8 * bits) +static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits) { int result = -ENODEV; @@ -476,7 +477,7 @@ static int dt9812_digital_out(struct slot_dt9812 *slot, u8 bits) return result; } -static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 * bits) +static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 *bits) { int result = -ENODEV; @@ -552,7 +553,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev, } } -static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 * value, +static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value, enum dt9812_gain gain) { struct dt9812_rmw_byte rmw[3]; @@ -619,7 +620,7 @@ exit: } static int dt9812_analog_out_shadow(struct slot_dt9812 *slot, int channel, - u16 * value) + u16 *value) { int result = -ENODEV; @@ -1110,9 +1111,9 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int dt9812_detach(struct comedi_device *dev) +static void dt9812_detach(struct comedi_device *dev) { - return 0; + /* Nothing to cleanup */ } static struct comedi_driver dt9812_comedi_driver = { diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index da8a2bf..b0cec7b 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -48,17 +48,6 @@ static DEFINE_MUTEX(start_stop_sem); -static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); - -static int dyna_pci10xx_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int dyna_pci10xx_detach(struct comedi_device *dev); - static const struct comedi_lrange range_pci1050_ai = { 3, { BIP_RANGE(10), BIP_RANGE(5), @@ -113,16 +102,6 @@ static const struct boardtype boardtypes[] = { {.name = DRV_NAME}, }; -static struct comedi_driver driver_dyna_pci10xx = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = dyna_pci10xx_attach, - .detach = dyna_pci10xx_detach, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), - .num_names = ARRAY_SIZE(boardtypes), -}; - struct dyna_pci10xx_private { struct pci_dev *pci_dev; /* ptr to PCI device */ char valid; /* card is usable */ @@ -408,54 +387,48 @@ found: return 1; } -static int dyna_pci10xx_detach(struct comedi_device *dev) +static void dyna_pci10xx_detach(struct comedi_device *dev) { if (devpriv && devpriv->pci_dev) { comedi_pci_disable(devpriv->pci_dev); mutex_destroy(&devpriv->mutex); } - - return 0; } -static int __devinit driver_dyna_pci10xx_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver dyna_pci10xx_driver = { + .driver_name = "dyna_pci10xx", + .module = THIS_MODULE, + .attach = dyna_pci10xx_attach, + .detach = dyna_pci10xx_detach, + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), + .num_names = ARRAY_SIZE(boardtypes), +}; + +static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_dyna_pci10xx.driver_name); + return comedi_pci_auto_config(dev, &dyna_pci10xx_driver); } -static void __devexit driver_dyna_pci10xx_pci_remove(struct pci_dev *dev) +static void __devexit dyna_pci10xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_dyna_pci10xx_pci_driver = { - .id_table = dyna_pci10xx_pci_table, - .probe = &driver_dyna_pci10xx_pci_probe, - .remove = __devexit_p(&driver_dyna_pci10xx_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); -static int __init driver_dyna_pci10xx_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_dyna_pci10xx); - if (retval < 0) - return retval; - - driver_dyna_pci10xx_pci_driver.name = - (char *)driver_dyna_pci10xx.driver_name; - return pci_register_driver(&driver_dyna_pci10xx_pci_driver); -} - -static void __exit driver_dyna_pci10xx_cleanup_module(void) -{ - pci_unregister_driver(&driver_dyna_pci10xx_pci_driver); - comedi_driver_unregister(&driver_dyna_pci10xx); -} - -module_init(driver_dyna_pci10xx_init_module); -module_exit(driver_dyna_pci10xx_cleanup_module); +static struct pci_driver dyna_pci10xx_pci_driver = { + .name = "dyna_pci10xx", + .id_table = dyna_pci10xx_pci_table, + .probe = dyna_pci10xx_pci_probe, + .remove = __devexit_p(dyna_pci10xx_pci_remove), +}; +module_comedi_pci_driver(dyna_pci10xx_driver, dyna_pci10xx_pci_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Prashant Shah <pshah.mumbai@gmail.com>"); diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 7f49add..d2381445 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -42,38 +42,6 @@ static const struct comedi_lrange range_fl512 = { 4, { } }; -static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int fl512_detach(struct comedi_device *dev); - -static struct comedi_driver driver_fl512 = { - .driver_name = "fl512", - .module = THIS_MODULE, - .attach = fl512_attach, - .detach = fl512_detach, -}; - -static int __init driver_fl512_init_module(void) -{ - return comedi_driver_register(&driver_fl512); -} - -static void __exit driver_fl512_cleanup_module(void) -{ - comedi_driver_unregister(&driver_fl512); -} - -module_init(driver_fl512_init_module); -module_exit(driver_fl512_cleanup_module); - -static int fl512_ai_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int fl512_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int fl512_ao_insn_readback(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /* * fl512_ai_insn : this is the analog input function */ @@ -140,9 +108,6 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, return n; } -/* - * start attach - */ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { unsigned long iobase; @@ -209,14 +174,20 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -static int fl512_detach(struct comedi_device *dev) +static void fl512_detach(struct comedi_device *dev) { if (dev->iobase) release_region(dev->iobase, FL512_SIZE); - printk(KERN_INFO "comedi%d: fl512: dummy i detach\n", dev->minor); - return 0; } +static struct comedi_driver fl512_driver = { + .driver_name = "fl512", + .module = THIS_MODULE, + .attach = fl512_attach, + .detach = fl512_detach, +}; +module_comedi_driver(fl512_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index bc020de..8aece08 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -53,8 +53,6 @@ support could be added to this driver. #include "plx9080.h" #include "comedi_fc.h" -static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int hpdi_detach(struct comedi_device *dev); static void abort_dma(struct comedi_device *dev, unsigned int channel); static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, @@ -287,15 +285,6 @@ static const struct hpdi_board hpdi_boards[] = { #endif }; -static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = { - { - PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, - 0x2400, 0, 0, 0}, { - 0} -}; - -MODULE_DEVICE_TABLE(pci, hpdi_pci_table); - static inline struct hpdi_board *board(const struct comedi_device *dev) { return (struct hpdi_board *)dev->board_ptr; @@ -338,51 +327,6 @@ static inline struct hpdi_private *priv(struct comedi_device *dev) return dev->private; } -static struct comedi_driver driver_hpdi = { - .driver_name = "gsc_hpdi", - .module = THIS_MODULE, - .attach = hpdi_attach, - .detach = hpdi_detach, -}; - -static int __devinit driver_hpdi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_hpdi.driver_name); -} - -static void __devexit driver_hpdi_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_hpdi_pci_driver = { - .id_table = hpdi_pci_table, - .probe = &driver_hpdi_pci_probe, - .remove = __devexit_p(&driver_hpdi_pci_remove) -}; - -static int __init driver_hpdi_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_hpdi); - if (retval < 0) - return retval; - - driver_hpdi_pci_driver.name = (char *)driver_hpdi.driver_name; - return pci_register_driver(&driver_hpdi_pci_driver); -} - -static void __exit driver_hpdi_cleanup_module(void) -{ - pci_unregister_driver(&driver_hpdi_pci_driver); - comedi_driver_unregister(&driver_hpdi); -} - -module_init(driver_hpdi_init_module); -module_exit(driver_hpdi_cleanup_module); - static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -645,7 +589,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name, pcidev->bus->number, PCI_SLOT(pcidev->devfn)); - if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) { + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { printk(KERN_WARNING " failed enable PCI device and request regions\n"); return -EIO; @@ -679,7 +623,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - driver_hpdi.driver_name, dev)) { + dev->driver->driver_name, dev)) { printk(KERN_WARNING " unable to allocate irq %u\n", pcidev->irq); return -EINVAL; @@ -720,12 +664,10 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) return init_hpdi(dev); } -static int hpdi_detach(struct comedi_device *dev) +static void hpdi_detach(struct comedi_device *dev) { unsigned int i; - printk(KERN_WARNING "comedi%d: gsc_hpdi: remove\n", dev->minor); - if (dev->irq) free_irq(dev->irq, dev); if ((priv(dev)) && (priv(dev)->hw_dev)) { @@ -758,7 +700,6 @@ static int hpdi_detach(struct comedi_device *dev) comedi_pci_disable(priv(dev)->hw_dev); pci_dev_put(priv(dev)->hw_dev); } - return 0; } static int dio_config_block_size(struct comedi_device *dev, unsigned int *data) @@ -1113,6 +1054,39 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } +static struct comedi_driver gsc_hpdi_driver = { + .driver_name = "gsc_hpdi", + .module = THIS_MODULE, + .attach = hpdi_attach, + .detach = hpdi_detach, +}; + +static int __devinit gsc_hpdi_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &gsc_hpdi_driver); +} + +static void __devexit gsc_hpdi_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(gsc_hpdi_pci_table) = { + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, + 0x2400, 0, 0, 0}, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table); + +static struct pci_driver gsc_hpdi_pci_driver = { + .name = "gsc_hpdi", + .id_table = gsc_hpdi_pci_table, + .probe = gsc_hpdi_pci_probe, + .remove = __devexit_p(gsc_hpdi_pci_remove) +}; +module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 126550f..fdc596f 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -121,15 +121,6 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 }; /* ============================================================================== - Forward declarations -============================================================================== -*/ -static int icp_multi_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int icp_multi_detach(struct comedi_device *dev); - -/* -============================================================================== Data & Structure declarations ============================================================================== */ @@ -154,50 +145,6 @@ struct boardtype { const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ }; -static const struct boardtype boardtypes[] = { - {"icp_multi", /* Driver name */ - DEVICE_ID, /* PCI device ID */ - IORANGE_ICP_MULTI, /* I/O range length */ - 1, /* 1=Card supports interrupts */ - TYPE_ICP_MULTI, /* Card type = ICP MULTI */ - 16, /* Num of A/D channels */ - 8, /* Num of A/D channels in diff mode */ - 4, /* Num of D/A channels */ - 16, /* Num of digital inputs */ - 8, /* Num of digital outputs */ - 4, /* Num of counters */ - 0x0fff, /* Resolution of A/D */ - 0x0fff, /* Resolution of D/A */ - &range_analog, /* Rangelist for A/D */ - range_codes_analog, /* Range codes for programming */ - &range_analog}, /* Rangelist for D/A */ -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) - -static struct comedi_driver driver_icp_multi = { - .driver_name = "icp_multi", - .module = THIS_MODULE, - .attach = icp_multi_attach, - .detach = icp_multi_detach, - .num_names = n_boardtypes, - .board_name = &boardtypes[0].name, - .offset = sizeof(struct boardtype), -}; - -static int __init driver_icp_multi_init_module(void) -{ - return comedi_driver_register(&driver_icp_multi); -} - -static void __exit driver_icp_multi_cleanup_module(void) -{ - comedi_driver_unregister(&driver_icp_multi); -} - -module_init(driver_icp_multi_init_module); -module_exit(driver_icp_multi_cleanup_module); - struct icp_multi_private { struct pcilst_struct *card; /* pointer to card */ char valid; /* card is usable */ @@ -222,25 +169,81 @@ struct icp_multi_private { /* ============================================================================== - More forward declarations + +Name: setup_channel_list + +Description: + This function sets the appropriate channel selection, + differential input mode and range bits in the ADC Command/ + Status register. + +Parameters: + struct comedi_device *dev Pointer to current service structure + struct comedi_subdevice *s Pointer to current subdevice structure + unsigned int *chanlist Pointer to packed channel list + unsigned int n_chan Number of channels to scan + +Returns:Void + ============================================================================== */ - -#if 0 -static int check_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan); -#endif static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan); -static int icp_multi_reset(struct comedi_device *dev); + unsigned int *chanlist, unsigned int n_chan) +{ + unsigned int i, range, chanprog; + unsigned int diff; -/* -============================================================================== - Functions -============================================================================== -*/ +#ifdef ICP_MULTI_EXTDEBUG + printk(KERN_DEBUG + "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); +#endif + devpriv->act_chanlist_len = n_chan; + devpriv->act_chanlist_pos = 0; + + for (i = 0; i < n_chan; i++) { + /* Get channel */ + chanprog = CR_CHAN(chanlist[i]); + + /* Determine if it is a differential channel (Bit 15 = 1) */ + if (CR_AREF(chanlist[i]) == AREF_DIFF) { + diff = 1; + chanprog &= 0x0007; + } else { + diff = 0; + chanprog &= 0x000f; + } + + /* Clear channel, range and input mode bits + * in A/D command/status register */ + devpriv->AdcCmdStatus &= 0xf00f; + + /* Set channel number and differential mode status bit */ + if (diff) { + /* Set channel number, bits 9-11 & mode, bit 6 */ + devpriv->AdcCmdStatus |= (chanprog << 9); + devpriv->AdcCmdStatus |= ADC_DI; + } else + /* Set channel number, bits 8-11 */ + devpriv->AdcCmdStatus |= (chanprog << 8); + + /* Get range for current channel */ + range = this_board->rangecode[CR_RANGE(chanlist[i])]; + /* Set range. bits 4-5 */ + devpriv->AdcCmdStatus |= range; + + /* Output channel, range, mode to ICP Multi */ + writew(devpriv->AdcCmdStatus, + devpriv->io_addr + ICP_MULTI_ADC_CSR); + +#ifdef ICP_MULTI_EXTDEBUG + printk(KERN_DEBUG + "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, + devpriv->act_chanlist[i]); +#endif + } + +} /* ============================================================================== @@ -764,84 +767,6 @@ static int check_channel_list(struct comedi_device *dev, /* ============================================================================== -Name: setup_channel_list - -Description: - This function sets the appropriate channel selection, - differential input mode and range bits in the ADC Command/ - Status register. - -Parameters: - struct comedi_device *dev Pointer to current service structure - struct comedi_subdevice *s Pointer to current subdevice structure - unsigned int *chanlist Pointer to packed channel list - unsigned int n_chan Number of channels to scan - -Returns:Void - -============================================================================== -*/ -static void setup_channel_list(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int *chanlist, unsigned int n_chan) -{ - unsigned int i, range, chanprog; - unsigned int diff; - -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "icp multi EDBG: setup_channel_list(...,%d)\n", n_chan); -#endif - devpriv->act_chanlist_len = n_chan; - devpriv->act_chanlist_pos = 0; - - for (i = 0; i < n_chan; i++) { - /* Get channel */ - chanprog = CR_CHAN(chanlist[i]); - - /* Determine if it is a differential channel (Bit 15 = 1) */ - if (CR_AREF(chanlist[i]) == AREF_DIFF) { - diff = 1; - chanprog &= 0x0007; - } else { - diff = 0; - chanprog &= 0x000f; - } - - /* Clear channel, range and input mode bits - * in A/D command/status register */ - devpriv->AdcCmdStatus &= 0xf00f; - - /* Set channel number and differential mode status bit */ - if (diff) { - /* Set channel number, bits 9-11 & mode, bit 6 */ - devpriv->AdcCmdStatus |= (chanprog << 9); - devpriv->AdcCmdStatus |= ADC_DI; - } else - /* Set channel number, bits 8-11 */ - devpriv->AdcCmdStatus |= (chanprog << 8); - - /* Get range for current channel */ - range = this_board->rangecode[CR_RANGE(chanlist[i])]; - /* Set range. bits 4-5 */ - devpriv->AdcCmdStatus |= range; - - /* Output channel, range, mode to ICP Multi */ - writew(devpriv->AdcCmdStatus, - devpriv->io_addr + ICP_MULTI_ADC_CSR); - -#ifdef ICP_MULTI_EXTDEBUG - printk(KERN_DEBUG - "GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range, - devpriv->act_chanlist[i]); -#endif - } - -} - -/* -============================================================================== - Name: icp_multi_reset Description: @@ -897,23 +822,6 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -/* -============================================================================== - -Name: icp_multi_attach - -Description: - This function sets up all the appropriate data for the current - device. - -Parameters: - struct comedi_device *dev Pointer to current device structure - struct comedi_devconfig *it Pointer to current device configuration - -Returns:int 0 = success - -============================================================================== -*/ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1099,44 +1007,53 @@ static int icp_multi_attach(struct comedi_device *dev, return 0; } -/* -============================================================================== - -Name: icp_multi_detach - -Description: - This function releases all the resources used by the current - device. - -Parameters: - struct comedi_device *dev Pointer to current device structure - -Returns:int 0 = success - -============================================================================== -*/ -static int icp_multi_detach(struct comedi_device *dev) +static void icp_multi_detach(struct comedi_device *dev) { - if (dev->private) if (devpriv->valid) icp_multi_reset(dev); - if (dev->irq) free_irq(dev->irq, dev); - if (dev->private && devpriv->io_addr) iounmap(devpriv->io_addr); - if (dev->private && devpriv->card) pci_card_free(devpriv->card); - if (--pci_list_builded == 0) pci_card_list_cleanup(PCI_VENDOR_ID_ICP); - - return 0; } +static const struct boardtype boardtypes[] = { + { + .name = "icp_multi", + .device_id = DEVICE_ID, + .iorange = IORANGE_ICP_MULTI, + .have_irq = 1, + .cardtype = TYPE_ICP_MULTI, + .n_aichan = 16, + .n_aichand = 8, + .n_aochan = 4, + .n_dichan = 16, + .n_dochan = 8, + .n_ctrs = 4, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_analog, + .rangecode = range_codes_analog, + .rangelist_ao = &range_analog, + }, +}; + +static struct comedi_driver icp_multi_driver = { + .driver_name = "icp_multi", + .module = THIS_MODULE, + .attach = icp_multi_attach, + .detach = icp_multi_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), +}; +module_comedi_driver(icp_multi_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index e4711ef..f0a579a 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -159,17 +159,6 @@ struct pci20xxx_private { #define devpriv ((struct pci20xxx_private *)dev->private) #define CHAN (CR_CHAN(it->chanlist[0])) -static int pci20xxx_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pci20xxx_detach(struct comedi_device *dev); - -static struct comedi_driver driver_pci20xxx = { - .driver_name = "ii_pci20kc", - .module = THIS_MODULE, - .attach = pci20xxx_attach, - .detach = pci20xxx_detach, -}; - static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s, int opt0, int opt1); static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s, @@ -275,11 +264,9 @@ static int pci20xxx_attach(struct comedi_device *dev, return 1; } -static int pci20xxx_detach(struct comedi_device *dev) +static void pci20xxx_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pci20xxx: remove\n", dev->minor); - - return 0; + /* Nothing to cleanup */ } /* pci20006m */ @@ -666,18 +653,13 @@ static unsigned int pci20xxx_di(struct comedi_device *dev, } #endif -static int __init driver_pci20xxx_init_module(void) -{ - return comedi_driver_register(&driver_pci20xxx); -} - -static void __exit driver_pci20xxx_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pci20xxx); -} - -module_init(driver_pci20xxx_init_module); -module_exit(driver_pci20xxx_cleanup_module); +static struct comedi_driver pci20xxx_driver = { + .driver_name = "ii_pci20kc", + .module = THIS_MODULE, + .attach = pci20xxx_attach, + .detach = pci20xxx_detach, +}; +module_comedi_driver(pci20xxx_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 6a79ba1..d536a11 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -59,28 +59,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113 #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 -static int jr3_pci_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int jr3_pci_detach(struct comedi_device *dev); - -static struct comedi_driver driver_jr3_pci = { - .driver_name = "jr3_pci", - .module = THIS_MODULE, - .attach = jr3_pci_attach, - .detach = jr3_pci_detach, -}; - -static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL) }, - { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table); - struct jr3_pci_dev_private { struct pci_dev *pci_dev; @@ -948,9 +926,7 @@ out: return result; } -MODULE_FIRMWARE("comedi/jr3pci.idm"); - -static int jr3_pci_detach(struct comedi_device *dev) +static void jr3_pci_detach(struct comedi_device *dev) { int i; struct jr3_pci_dev_private *devpriv = dev->private; @@ -962,56 +938,52 @@ static int jr3_pci_detach(struct comedi_device *dev) for (i = 0; i < devpriv->n_channels; i++) kfree(dev->subdevices[i].private); } - if (devpriv->iobase) iounmap((void *)devpriv->iobase); if (devpriv->pci_enabled) comedi_pci_disable(devpriv->pci_dev); - if (devpriv->pci_dev) pci_dev_put(devpriv->pci_dev); } - return 0; } -static int __devinit driver_jr3_pci_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver jr3_pci_driver = { + .driver_name = "jr3_pci", + .module = THIS_MODULE, + .attach = jr3_pci_attach, + .detach = jr3_pci_detach, +}; + +static int __devinit jr3_pci_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_jr3_pci.driver_name); + return comedi_pci_auto_config(dev, &jr3_pci_driver); } -static void __devexit driver_jr3_pci_pci_remove(struct pci_dev *dev) +static void __devexit jr3_pci_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_jr3_pci_pci_driver = { - .id_table = jr3_pci_pci_table, - .probe = &driver_jr3_pci_pci_probe, - .remove = __devexit_p(&driver_jr3_pci_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL) }, + { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table); -static int __init driver_jr3_pci_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_jr3_pci); - if (retval < 0) - return retval; - - driver_jr3_pci_pci_driver.name = (char *)driver_jr3_pci.driver_name; - return pci_register_driver(&driver_jr3_pci_pci_driver); -} - -static void __exit driver_jr3_pci_cleanup_module(void) -{ - pci_unregister_driver(&driver_jr3_pci_pci_driver); - comedi_driver_unregister(&driver_jr3_pci); -} - -module_init(driver_jr3_pci_init_module); -module_exit(driver_jr3_pci_cleanup_module); +static struct pci_driver jr3_pci_pci_driver = { + .name = "jr3_pci", + .id_table = jr3_pci_pci_table, + .probe = jr3_pci_pci_probe, + .remove = __devexit_p(jr3_pci_pci_remove), +}; +module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("comedi/jr3pci.idm"); diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 4e9e9a0..09d1918 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -46,18 +46,6 @@ Kolter Electronic PCI Counter Card. #define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 -/*-- function prototypes ----------------------------------------------------*/ - -static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int cnt_detach(struct comedi_device *dev); - -static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, cnt_pci_table); - /*-- board specification structure ------------------------------------------*/ struct cnt_board_struct { @@ -87,51 +75,6 @@ struct cnt_device_private { #define devpriv ((struct cnt_device_private *)dev->private) -static struct comedi_driver cnt_driver = { - .driver_name = CNT_DRIVER_NAME, - .module = THIS_MODULE, - .attach = cnt_attach, - .detach = cnt_detach, -}; - -static int __devinit cnt_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, cnt_driver.driver_name); -} - -static void __devexit cnt_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver cnt_driver_pci_driver = { - .id_table = cnt_pci_table, - .probe = &cnt_driver_pci_probe, - .remove = __devexit_p(&cnt_driver_pci_remove) -}; - -static int __init cnt_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&cnt_driver); - if (retval < 0) - return retval; - - cnt_driver_pci_driver.name = (char *)cnt_driver.driver_name; - return pci_register_driver(&cnt_driver_pci_driver); -} - -static void __exit cnt_driver_cleanup_module(void) -{ - pci_unregister_driver(&cnt_driver_pci_driver); - comedi_driver_unregister(&cnt_driver); -} - -module_init(cnt_driver_init_module); -module_exit(cnt_driver_cleanup_module); - /*-- counter write ----------------------------------------------------------*/ /* This should be used only for resetting the counters; maybe it is better @@ -181,8 +124,6 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -/*-- attach -----------------------------------------------------------------*/ - static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *subdevice; @@ -278,20 +219,47 @@ found: return 0; } -/*-- detach -----------------------------------------------------------------*/ - -static int cnt_detach(struct comedi_device *dev) +static void cnt_detach(struct comedi_device *dev) { if (devpriv && devpriv->pcidev) { if (dev->iobase) comedi_pci_disable(devpriv->pcidev); pci_dev_put(devpriv->pcidev); } - printk(KERN_INFO "comedi%d: " CNT_DRIVER_NAME " remove\n", - dev->minor); - return 0; } +static struct comedi_driver ke_counter_driver = { + .driver_name = "ke_counter", + .module = THIS_MODULE, + .attach = cnt_attach, + .detach = cnt_detach, +}; + +static int __devinit ke_counter_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &ke_counter_driver); +} + +static void __devexit ke_counter_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(ke_counter_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ke_counter_pci_table); + +static struct pci_driver ke_counter_pci_driver = { + .name = "ke_counter", + .id_table = ke_counter_pci_table, + .probe = ke_counter_pci_probe, + .remove = __devexit_p(ke_counter_pci_remove), +}; +module_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index b0bc6bb..8ca1b546 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -65,30 +65,6 @@ broken. #include "me4000_fw.h" #endif -/*============================================================================= - PCI device table. - This is used by modprobe to translate PCI IDs to drivers. - ===========================================================================*/ - -static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, me4000_pci_table); - static const struct me4000_board me4000_boards[] = { {"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0} }, @@ -113,22 +89,8 @@ static const struct me4000_board me4000_boards[] = { #define ME4000_BOARD_VERSIONS (ARRAY_SIZE(me4000_boards) - 1) /*----------------------------------------------------------------------------- - Comedi function prototypes - ---------------------------------------------------------------------------*/ -static int me4000_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int me4000_detach(struct comedi_device *dev); -static struct comedi_driver driver_me4000 = { - .driver_name = "me4000", - .module = THIS_MODULE, - .attach = me4000_attach, - .detach = me4000_detach, -}; - -/*----------------------------------------------------------------------------- Meilhaus function prototypes ---------------------------------------------------------------------------*/ -static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it); static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p); static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p); @@ -139,76 +101,10 @@ static int init_cnt_context(struct comedi_device *dev); static int xilinx_download(struct comedi_device *dev); static int reset_board(struct comedi_device *dev); -static int me4000_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int cnt_reset(struct comedi_device *dev, unsigned int channel); - -static int cnt_config(struct comedi_device *dev, - unsigned int channel, unsigned int mode); - -static int me4000_cnt_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_cnt_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_cnt_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *subdevice, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); - -static int ai_check_chanlist(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -static int ai_round_cmd_args(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd, - unsigned int *init_ticks, - unsigned int *scan_ticks, - unsigned int *chan_ticks); - -static int ai_prepare(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd, - unsigned int init_ticks, - unsigned int scan_ticks, unsigned int chan_ticks); - static int ai_write_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); -static irqreturn_t me4000_ai_isr(int irq, void *dev_id); - -static int me4000_ai_do_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -static int me4000_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); - -static int me4000_ao_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int me4000_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - /*----------------------------------------------------------------------------- Meilhaus inline functions ---------------------------------------------------------------------------*/ @@ -262,130 +158,6 @@ static const struct comedi_lrange me4000_ao_range = { } }; -static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int result; - - CALL_PDEBUG("In me4000_attach()\n"); - - result = me4000_probe(dev, it); - if (result) - return result; - - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. It relies on - * n_subdevices being set correctly. - */ - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - /*========================================================================= - Analog input subdevice - ========================================================================*/ - - s = dev->subdevices + 0; - - if (thisboard->ai.count) { - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai.count; - s->maxdata = 0xFFFF; /* 16 bit ADC */ - s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; - s->range_table = &me4000_ai_range; - s->insn_read = me4000_ai_insn_read; - - if (info->irq > 0) { - if (request_irq(info->irq, me4000_ai_isr, - IRQF_SHARED, "ME-4000", dev)) { - printk - ("comedi%d: me4000: me4000_attach(): " - "Unable to allocate irq\n", dev->minor); - } else { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = me4000_ai_cancel; - s->do_cmdtest = me4000_ai_do_cmd_test; - s->do_cmd = me4000_ai_do_cmd; - } - } else { - printk(KERN_WARNING - "comedi%d: me4000: me4000_attach(): " - "No interrupt available\n", dev->minor); - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /*========================================================================= - Analog output subdevice - ========================================================================*/ - - s = dev->subdevices + 1; - - if (thisboard->ao.count) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; - s->n_chan = thisboard->ao.count; - s->maxdata = 0xFFFF; /* 16 bit DAC */ - s->range_table = &me4000_ao_range; - s->insn_write = me4000_ao_insn_write; - s->insn_read = me4000_ao_insn_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /*========================================================================= - Digital I/O subdevice - ========================================================================*/ - - s = dev->subdevices + 2; - - if (thisboard->dio.count) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->dio.count * 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = me4000_dio_insn_bits; - s->insn_config = me4000_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* - * Check for optoisolated ME-4000 version. If one the first - * port is a fixed output port and the second is a fixed input port. - */ - if (!me4000_inl(dev, info->dio_context.dir_reg)) { - s->io_bits |= 0xFF; - me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, - info->dio_context.dir_reg); - } - - /*========================================================================= - Counter subdevice - ========================================================================*/ - - s = dev->subdevices + 3; - - if (thisboard->cnt.count) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = thisboard->cnt.count; - s->maxdata = 0xFFFF; /* 16 bit counters */ - s->insn_read = me4000_cnt_insn_read; - s->insn_write = me4000_cnt_insn_write; - s->insn_config = me4000_cnt_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - return 0; -} - static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device = NULL; @@ -920,22 +692,6 @@ static int reset_board(struct comedi_device *dev) return 0; } -static int me4000_detach(struct comedi_device *dev) -{ - CALL_PDEBUG("In me4000_detach()\n"); - - if (info) { - if (info->pci_dev_p) { - reset_board(dev); - if (info->plx_regbase) - comedi_pci_disable(info->pci_dev_p); - pci_dev_put(info->pci_dev_p); - } - } - - return 0; -} - /*============================================================================= Analog input section ===========================================================================*/ @@ -2424,43 +2180,185 @@ static int me4000_cnt_insn_write(struct comedi_device *dev, return 1; } -static int __devinit driver_me4000_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - return comedi_pci_auto_config(dev, driver_me4000.driver_name); + struct comedi_subdevice *s; + int result; + + CALL_PDEBUG("In me4000_attach()\n"); + + result = me4000_probe(dev, it); + if (result) + return result; + + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. It relies on + * n_subdevices being set correctly. + */ + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + /*========================================================================= + Analog input subdevice + ========================================================================*/ + + s = dev->subdevices + 0; + + if (thisboard->ai.count) { + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; + s->n_chan = thisboard->ai.count; + s->maxdata = 0xFFFF; /* 16 bit ADC */ + s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; + s->range_table = &me4000_ai_range; + s->insn_read = me4000_ai_insn_read; + + if (info->irq > 0) { + if (request_irq(info->irq, me4000_ai_isr, + IRQF_SHARED, "ME-4000", dev)) { + printk + ("comedi%d: me4000: me4000_attach(): " + "Unable to allocate irq\n", dev->minor); + } else { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = me4000_ai_cancel; + s->do_cmdtest = me4000_ai_do_cmd_test; + s->do_cmd = me4000_ai_do_cmd; + } + } else { + printk(KERN_WARNING + "comedi%d: me4000: me4000_attach(): " + "No interrupt available\n", dev->minor); + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /*========================================================================= + Analog output subdevice + ========================================================================*/ + + s = dev->subdevices + 1; + + if (thisboard->ao.count) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND; + s->n_chan = thisboard->ao.count; + s->maxdata = 0xFFFF; /* 16 bit DAC */ + s->range_table = &me4000_ao_range; + s->insn_write = me4000_ao_insn_write; + s->insn_read = me4000_ao_insn_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /*========================================================================= + Digital I/O subdevice + ========================================================================*/ + + s = dev->subdevices + 2; + + if (thisboard->dio.count) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = thisboard->dio.count * 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = me4000_dio_insn_bits; + s->insn_config = me4000_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* + * Check for optoisolated ME-4000 version. If one the first + * port is a fixed output port and the second is a fixed input port. + */ + if (!me4000_inl(dev, info->dio_context.dir_reg)) { + s->io_bits |= 0xFF; + me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0, + info->dio_context.dir_reg); + } + + /*========================================================================= + Counter subdevice + ========================================================================*/ + + s = dev->subdevices + 3; + + if (thisboard->cnt.count) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = thisboard->cnt.count; + s->maxdata = 0xFFFF; /* 16 bit counters */ + s->insn_read = me4000_cnt_insn_read; + s->insn_write = me4000_cnt_insn_write; + s->insn_config = me4000_cnt_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + return 0; } -static void __devexit driver_me4000_pci_remove(struct pci_dev *dev) +static void me4000_detach(struct comedi_device *dev) { - comedi_pci_auto_unconfig(dev); + if (info) { + if (info->pci_dev_p) { + reset_board(dev); + if (info->plx_regbase) + comedi_pci_disable(info->pci_dev_p); + pci_dev_put(info->pci_dev_p); + } + } } -static struct pci_driver driver_me4000_pci_driver = { - .id_table = me4000_pci_table, - .probe = &driver_me4000_pci_probe, - .remove = __devexit_p(&driver_me4000_pci_remove) +static struct comedi_driver me4000_driver = { + .driver_name = "me4000", + .module = THIS_MODULE, + .attach = me4000_attach, + .detach = me4000_detach, }; -static int __init driver_me4000_init_module(void) +static int __devinit me4000_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - int retval; - - retval = comedi_driver_register(&driver_me4000); - if (retval < 0) - return retval; - - driver_me4000_pci_driver.name = (char *)driver_me4000.driver_name; - return pci_register_driver(&driver_me4000_pci_driver); + return comedi_pci_auto_config(dev, &me4000_driver); } -static void __exit driver_me4000_cleanup_module(void) +static void __devexit me4000_pci_remove(struct pci_dev *dev) { - pci_unregister_driver(&driver_me4000_pci_driver); - comedi_driver_unregister(&driver_me4000); + comedi_pci_auto_unconfig(dev); } -module_init(driver_me4000_init_module); -module_exit(driver_me4000_cleanup_module); +static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4650) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4660) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4661) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4662) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4663) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4670) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4671) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4672) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4673) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4680) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4681) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4682) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, 0x4683) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, me4000_pci_table); + +static struct pci_driver me4000_pci_driver = { + .name = "me4000", + .id_table = me4000_pci_table, + .probe = me4000_pci_probe, + .remove = __devexit_p(me4000_pci_remove), +}; +module_comedi_pci_driver(me4000_driver, me4000_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 8b812e4..ffe2512 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -146,10 +146,6 @@ from http://www.comedi.org #define ME_COUNTER_STARTDATA_B 0x0022 /* - | W */ #define ME_COUNTER_VALUE_B 0x0022 /* R | - */ -/* Function prototypes */ -static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int me_detach(struct comedi_device *dev); - static const struct comedi_lrange me2000_ai_range = { 8, { @@ -187,14 +183,6 @@ static const struct comedi_lrange me2600_ao_range = { } }; -static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) }, - { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) }, - {0} -}; - -MODULE_DEVICE_TABLE(pci, me_pci_table); - /* Board specification structure */ struct me_board { const char *name; /* driver name */ @@ -247,51 +235,6 @@ static const struct me_board me_boards[] = { #define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board)) -static struct comedi_driver me_driver = { - .driver_name = ME_DRIVER_NAME, - .module = THIS_MODULE, - .attach = me_attach, - .detach = me_detach, -}; - -static int __devinit me_driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, me_driver.driver_name); -} - -static void __devexit me_driver_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver me_driver_pci_driver = { - .id_table = me_pci_table, - .probe = &me_driver_pci_probe, - .remove = __devexit_p(&me_driver_pci_remove) -}; - -static int __init me_driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&me_driver); - if (retval < 0) - return retval; - - me_driver_pci_driver.name = (char *)me_driver.driver_name; - return pci_register_driver(&me_driver_pci_driver); -} - -static void __exit me_driver_cleanup_module(void) -{ - pci_unregister_driver(&me_driver_pci_driver); - comedi_driver_unregister(&me_driver); -} - -module_init(me_driver_init_module); -module_exit(me_driver_cleanup_module); - /* Private data structure */ struct me_private_data { struct pci_dev *pci_device; @@ -669,12 +612,6 @@ static int me_reset(struct comedi_device *dev) return 0; } -/* - * Attach - * - * - Register PCI device - * - Declare device driver capability - */ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci_dev *pci_device = NULL; @@ -869,8 +806,7 @@ found: return 0; } -/* Detach */ -static int me_detach(struct comedi_device *dev) +static void me_detach(struct comedi_device *dev) { if (dev_private) { if (dev_private->me_regbase) { @@ -882,13 +818,44 @@ static int me_detach(struct comedi_device *dev) if (dev_private->pci_device) { if (dev_private->plx_regbase_size) comedi_pci_disable(dev_private->pci_device); - pci_dev_put(dev_private->pci_device); } } - return 0; } +static struct comedi_driver me_daq_driver = { + .driver_name = "me_daq", + .module = THIS_MODULE, + .attach = me_attach, + .detach = me_detach, +}; + +static int __devinit me_daq_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &me_daq_driver); +} + +static void __devexit me_daq_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, me_daq_pci_table); + +static struct pci_driver me_daq_pci_driver = { + .name = "me_daq", + .id_table = me_daq_pci_table, + .probe = me_daq_pci_probe, + .remove = __devexit_p(me_daq_pci_remove), +}; +module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 999551f..83f1b27 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -66,9 +66,9 @@ struct mite_struct { struct pci_dev *pcidev; resource_size_t mite_phys_addr; - void *mite_io_addr; + void __iomem *mite_io_addr; resource_size_t daq_phys_addr; - void *daq_io_addr; + void __iomem *daq_io_addr; struct mite_channel channels[MAX_MITE_DMA_CHANNELS]; short channel_allocated[MAX_MITE_DMA_CHANNELS]; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index dd09a6d..4304e86 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -148,131 +148,6 @@ static const struct comedi_lrange range_mpc624_bipolar10 = { } }; -/* -------------------------------------------------------------------------- */ -static int mpc624_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int mpc624_detach(struct comedi_device *dev); -/* -------------------------------------------------------------------------- */ -static struct comedi_driver driver_mpc624 = { - .driver_name = "mpc624", - .module = THIS_MODULE, - .attach = mpc624_attach, - .detach = mpc624_detach -}; - -/* -------------------------------------------------------------------------- */ -static int mpc624_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -/* -------------------------------------------------------------------------- */ -static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - - iobase = it->options[0]; - printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); - if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) { - printk(KERN_ERR "I/O port(s) in use\n"); - return -EIO; - } - - dev->iobase = iobase; - dev->board_name = "mpc624"; - - /* Private structure initialization */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) - return -ENOMEM; - - switch (it->options[1]) { - case 0: - devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; - printk(KERN_INFO "3.52 kHz, "); - break; - case 1: - devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz; - printk(KERN_INFO "1.76 kHz, "); - break; - case 2: - devpriv->ulConvertionRate = MPC624_SPEED_880_Hz; - printk(KERN_INFO "880 Hz, "); - break; - case 3: - devpriv->ulConvertionRate = MPC624_SPEED_440_Hz; - printk(KERN_INFO "440 Hz, "); - break; - case 4: - devpriv->ulConvertionRate = MPC624_SPEED_220_Hz; - printk(KERN_INFO "220 Hz, "); - break; - case 5: - devpriv->ulConvertionRate = MPC624_SPEED_110_Hz; - printk(KERN_INFO "110 Hz, "); - break; - case 6: - devpriv->ulConvertionRate = MPC624_SPEED_55_Hz; - printk(KERN_INFO "55 Hz, "); - break; - case 7: - devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz; - printk(KERN_INFO "27.5 Hz, "); - break; - case 8: - devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz; - printk(KERN_INFO "13.75 Hz, "); - break; - case 9: - devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz; - printk(KERN_INFO "6.875 Hz, "); - break; - default: - printk - (KERN_ERR "illegal conversion rate setting!" - " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); - devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; - } - - /* Subdevices structures */ - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF; - s->n_chan = 8; - switch (it->options[1]) { - default: - s->maxdata = 0x3FFFFFFF; - printk(KERN_INFO "30 bit, "); - } - - switch (it->options[1]) { - case 0: - s->range_table = &range_mpc624_bipolar1; - printk(KERN_INFO "1.01V]: "); - break; - default: - s->range_table = &range_mpc624_bipolar10; - printk(KERN_INFO "10.1V]: "); - } - s->len_chanlist = 1; - s->insn_read = mpc624_ai_rinsn; - - printk(KERN_INFO "attached\n"); - - return 1; -} - -static int mpc624_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: mpc624: remove\n", dev->minor); - - if (dev->iobase) - release_region(dev->iobase, MPC624_SIZE); - - return 0; -} - /* Timeout 200ms */ #define TIMEOUT 200 @@ -406,18 +281,117 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, return n; } -static int __init driver_mpc624_init_module(void) +static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - return comedi_driver_register(&driver_mpc624); + struct comedi_subdevice *s; + unsigned long iobase; + + iobase = it->options[0]; + printk(KERN_INFO "comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase); + if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) { + printk(KERN_ERR "I/O port(s) in use\n"); + return -EIO; + } + + dev->iobase = iobase; + dev->board_name = "mpc624"; + + /* Private structure initialization */ + if (alloc_private(dev, sizeof(struct skel_private)) < 0) + return -ENOMEM; + + switch (it->options[1]) { + case 0: + devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; + printk(KERN_INFO "3.52 kHz, "); + break; + case 1: + devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz; + printk(KERN_INFO "1.76 kHz, "); + break; + case 2: + devpriv->ulConvertionRate = MPC624_SPEED_880_Hz; + printk(KERN_INFO "880 Hz, "); + break; + case 3: + devpriv->ulConvertionRate = MPC624_SPEED_440_Hz; + printk(KERN_INFO "440 Hz, "); + break; + case 4: + devpriv->ulConvertionRate = MPC624_SPEED_220_Hz; + printk(KERN_INFO "220 Hz, "); + break; + case 5: + devpriv->ulConvertionRate = MPC624_SPEED_110_Hz; + printk(KERN_INFO "110 Hz, "); + break; + case 6: + devpriv->ulConvertionRate = MPC624_SPEED_55_Hz; + printk(KERN_INFO "55 Hz, "); + break; + case 7: + devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz; + printk(KERN_INFO "27.5 Hz, "); + break; + case 8: + devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz; + printk(KERN_INFO "13.75 Hz, "); + break; + case 9: + devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz; + printk(KERN_INFO "6.875 Hz, "); + break; + default: + printk + (KERN_ERR "illegal conversion rate setting!" + " Valid numbers are 0..9. Using 9 => 6.875 Hz, "); + devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz; + } + + /* Subdevices structures */ + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF; + s->n_chan = 8; + switch (it->options[1]) { + default: + s->maxdata = 0x3FFFFFFF; + printk(KERN_INFO "30 bit, "); + } + + switch (it->options[1]) { + case 0: + s->range_table = &range_mpc624_bipolar1; + printk(KERN_INFO "1.01V]: "); + break; + default: + s->range_table = &range_mpc624_bipolar10; + printk(KERN_INFO "10.1V]: "); + } + s->len_chanlist = 1; + s->insn_read = mpc624_ai_rinsn; + + printk(KERN_INFO "attached\n"); + + return 1; } -static void __exit driver_mpc624_cleanup_module(void) +static void mpc624_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver_mpc624); + if (dev->iobase) + release_region(dev->iobase, MPC624_SIZE); } -module_init(driver_mpc624_init_module); -module_exit(driver_mpc624_cleanup_module); +static struct comedi_driver mpc624_driver = { + .driver_name = "mpc624", + .module = THIS_MODULE, + .attach = mpc624_attach, + .detach = mpc624_detach +}; +module_comedi_driver(mpc624_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c index 5f6816a..364470e 100644 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ b/drivers/staging/comedi/drivers/mpc8260cpm.c @@ -46,75 +46,6 @@ struct mpc8260cpm_private { #define devpriv ((struct mpc8260cpm_private *)dev->private) -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int mpc8260cpm_detach(struct comedi_device *dev); -static struct comedi_driver driver_mpc8260cpm = { - .driver_name = "mpc8260cpm", - .module = THIS_MODULE, - .attach = mpc8260cpm_attach, - .detach = mpc8260cpm_detach, -}; - -static int __init driver_mpc8260cpm_init_module(void) -{ - return comedi_driver_register(&driver_mpc8260cpm); -} - -static void __exit driver_mpc8260cpm_cleanup_module(void) -{ - comedi_driver_unregister(&driver_mpc8260cpm); -} - -module_init(driver_mpc8260cpm_init_module); -module_exit(driver_mpc8260cpm_cleanup_module); - -static int mpc8260cpm_dio_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int mpc8260cpm_dio_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int i; - - printk("comedi%d: mpc8260cpm: ", dev->minor); - - dev->board_ptr = mpc8260cpm_boards + dev->board; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) - return -ENOMEM; - - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - for (i = 0; i < 4; i++) { - s = dev->subdevices + i; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 32; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = mpc8260cpm_dio_config; - s->insn_bits = mpc8260cpm_dio_bits; - } - - return 1; -} - -static int mpc8260cpm_detach(struct comedi_device *dev) -{ - printk("comedi%d: mpc8260cpm: remove\n", dev->minor); - - return 0; -} - static unsigned long *cpm_pdat(int port) { switch (port) { @@ -184,3 +115,48 @@ static int mpc8260cpm_dio_bits(struct comedi_device *dev, return 2; } + +static int mpc8260cpm_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int i; + + printk("comedi%d: mpc8260cpm: ", dev->minor); + + dev->board_ptr = mpc8260cpm_boards + dev->board; + + dev->board_name = thisboard->name; + + if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + for (i = 0; i < 4; i++) { + s = dev->subdevices + i; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 32; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = mpc8260cpm_dio_config; + s->insn_bits = mpc8260cpm_dio_bits; + } + + return 1; +} + +static void mpc8260cpm_detach(struct comedi_device *dev) +{ + /* Nothing to cleanup */ +} + +static struct comedi_driver mpc8260cpm_driver = { + .driver_name = "mpc8260cpm", + .module = THIS_MODULE, + .attach = mpc8260cpm_attach, + .detach = mpc8260cpm_detach, +}; +module_comedi_driver(mpc8260cpm_driver); diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index dace902..e951e73 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -83,29 +83,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3) #define MULTIQ3_TIMEOUT 30 -static int multiq3_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int multiq3_detach(struct comedi_device *dev); -static struct comedi_driver driver_multiq3 = { - .driver_name = "multiq3", - .module = THIS_MODULE, - .attach = multiq3_attach, - .detach = multiq3_detach, -}; - -static int __init driver_multiq3_init_module(void) -{ - return comedi_driver_register(&driver_multiq3); -} - -static void __exit driver_multiq3_cleanup_module(void) -{ - comedi_driver_unregister(&driver_multiq3); -} - -module_init(driver_multiq3_init_module); -module_exit(driver_multiq3_cleanup_module); - struct multiq3_private { unsigned int ao_readback[2]; }; @@ -338,18 +315,22 @@ static int multiq3_attach(struct comedi_device *dev, return 0; } -static int multiq3_detach(struct comedi_device *dev) +static void multiq3_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: multiq3: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, MULTIQ3_SIZE); if (dev->irq) free_irq(dev->irq, dev); - - return 0; } +static struct comedi_driver multiq3_driver = { + .driver_name = "multiq3", + .module = THIS_MODULE, + .attach = multiq3_attach, + .detach = multiq3_detach, +}; +module_comedi_driver(multiq3_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 54741c9..b02aa0e 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -78,7 +78,7 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int ni6527_detach(struct comedi_device *dev); +static void ni6527_detach(struct comedi_device *dev); static struct comedi_driver driver_ni6527 = { .driver_name = "ni6527", .module = THIS_MODULE, @@ -449,19 +449,15 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int ni6527_detach(struct comedi_device *dev) +static void ni6527_detach(struct comedi_device *dev) { if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); - if (dev->irq) free_irq(dev->irq, dev); - if (devpriv && devpriv->mite) mite_unsetup(devpriv->mite); - - return 0; } static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) @@ -493,7 +489,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot) static int __devinit driver_ni6527_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni6527.driver_name); + return comedi_pci_auto_config(dev, &driver_ni6527); } static void __devexit driver_ni6527_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 403fc09..0d27a93 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -111,7 +111,7 @@ static inline unsigned Filter_Enable(unsigned port) static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int ni_65xx_detach(struct comedi_device *dev); +static void ni_65xx_detach(struct comedi_device *dev); static struct comedi_driver driver_ni_65xx = { .driver_name = "ni_65xx", .module = THIS_MODULE, @@ -784,7 +784,7 @@ static int ni_65xx_attach(struct comedi_device *dev, return 0; } -static int ni_65xx_detach(struct comedi_device *dev) +static void ni_65xx_detach(struct comedi_device *dev) { if (private(dev) && private(dev)->mite && private(dev)->mite->daq_io_addr) { @@ -792,10 +792,8 @@ static int ni_65xx_detach(struct comedi_device *dev) private(dev)->mite->daq_io_addr + Master_Interrupt_Control); } - if (dev->irq) free_irq(dev->irq, dev); - if (private(dev)) { unsigned i; for (i = 0; i < dev->n_subdevices; ++i) { @@ -805,7 +803,6 @@ static int ni_65xx_detach(struct comedi_device *dev) if (private(dev)->mite) mite_unsetup(private(dev)->mite); } - return 0; } static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) @@ -837,7 +834,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot) static int __devinit driver_ni_65xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_65xx.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_65xx); } static void __devexit driver_ni_65xx_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 35f3a47..8c40730 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -458,7 +458,7 @@ static inline const struct ni_660x_board *board(struct comedi_device *dev) static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int ni_660x_detach(struct comedi_device *dev); +static void ni_660x_detach(struct comedi_device *dev); static void init_tio_chip(struct comedi_device *dev, int chipset); static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel, @@ -474,7 +474,7 @@ static struct comedi_driver driver_ni_660x = { static int __devinit driver_ni_660x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_660x.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_660x); } static void __devexit driver_ni_660x_pci_remove(struct pci_dev *dev) @@ -761,7 +761,7 @@ static inline void ni_660x_write_register(struct comedi_device *dev, unsigned chip_index, unsigned bits, enum NI_660x_Register reg) { - void *const write_address = + void __iomem *write_address = private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; @@ -784,7 +784,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, unsigned chip_index, enum NI_660x_Register reg) { - void *const read_address = + void __iomem *read_address = private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; @@ -1188,14 +1188,10 @@ static int ni_660x_attach(struct comedi_device *dev, return 0; } -static int ni_660x_detach(struct comedi_device *dev) +static void ni_660x_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor); - - /* Free irq */ if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { if (private(dev)->counter_dev) ni_gpct_device_destroy(private(dev)->counter_dev); @@ -1204,7 +1200,6 @@ static int ni_660x_detach(struct comedi_device *dev) mite_unsetup(private(dev)->mite); } } - return 0; } static int diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index d8d91f9..a9cf94f 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -111,7 +111,7 @@ struct ni_670x_private { static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int ni_670x_detach(struct comedi_device *dev); +static void ni_670x_detach(struct comedi_device *dev); static struct comedi_driver driver_ni_670x = { .driver_name = "ni_670x", @@ -123,7 +123,7 @@ static struct comedi_driver driver_ni_670x = { static int __devinit driver_ni_670x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_ni_670x.driver_name); + return comedi_pci_auto_config(dev, &driver_ni_670x); } static void __devexit driver_ni_670x_pci_remove(struct pci_dev *dev) @@ -249,19 +249,13 @@ static int ni_670x_attach(struct comedi_device *dev, return 1; } -static int ni_670x_detach(struct comedi_device *dev) +static void ni_670x_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: ni_670x: remove\n", dev->minor); - kfree(dev->subdevices[0].range_table_list); - if (dev->private && devpriv->mite) mite_unsetup(devpriv->mite); - if (dev->irq) free_irq(dev->irq, dev); - - return 0; } static int ni_670x_ao_winsn(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index c25e44c..ae896a0 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -171,46 +171,13 @@ struct a2150_private { #define devpriv ((struct a2150_private *)dev->private) -static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int a2150_detach(struct comedi_device *dev); static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static struct comedi_driver driver_a2150 = { - .driver_name = "ni_at_a2150", - .module = THIS_MODULE, - .attach = a2150_attach, - .detach = a2150_detach, -}; - -static irqreturn_t a2150_interrupt(int irq, void *d); -static int a2150_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); -static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, int flags); -static int a2150_probe(struct comedi_device *dev); static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel, unsigned int num_channels); -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __init driver_a2150_init_module(void) -{ - return comedi_driver_register(&driver_a2150); -} - -static void __exit driver_a2150_cleanup_module(void) -{ - comedi_driver_unregister(&driver_a2150); -} - -module_init(driver_a2150_init_module); -module_exit(driver_a2150_cleanup_module); - #ifdef A2150_DEBUG static void ni_dump_regs(struct comedi_device *dev) @@ -331,161 +298,6 @@ static irqreturn_t a2150_interrupt(int irq, void *d) return IRQ_HANDLED; } -/* probes board type, returns offset */ -static int a2150_probe(struct comedi_device *dev) -{ - int status = inw(dev->iobase + STATUS_REG); - return ID_BITS(status); -} - -static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase = it->options[0]; - unsigned int irq = it->options[1]; - unsigned int dma = it->options[2]; - static const int timeout = 2000; - int i; - - printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name, - iobase); - if (irq) { - printk(", irq %u", irq); - } else { - printk(", no irq"); - } - if (dma) { - printk(", dma %u", dma); - } else { - printk(", no dma"); - } - printk("\n"); - - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct a2150_private)) < 0) - return -ENOMEM; - - if (iobase == 0) { - printk(" io base address required\n"); - return -EINVAL; - } - - /* check if io addresses are available */ - if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) { - printk(" I/O port conflict\n"); - return -EIO; - } - dev->iobase = iobase; - - /* grab our IRQ */ - if (irq) { - /* check that irq is supported */ - if (irq < 3 || irq == 8 || irq == 13 || irq > 15) { - printk(" invalid irq line %u\n", irq); - return -EINVAL; - } - if (request_irq(irq, a2150_interrupt, 0, - driver_a2150.driver_name, dev)) { - printk("unable to allocate irq %u\n", irq); - return -EINVAL; - } - devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); - dev->irq = irq; - } - /* initialize dma */ - if (dma) { - if (dma == 4 || dma > 7) { - printk(" invalid dma channel %u\n", dma); - return -EINVAL; - } - if (request_dma(dma, driver_a2150.driver_name)) { - printk(" failed to allocate dma channel %u\n", dma); - return -EINVAL; - } - devpriv->dma = dma; - devpriv->dma_buffer = - kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->dma_buffer == NULL) - return -ENOMEM; - - disable_dma(dma); - set_dma_mode(dma, DMA_MODE_READ); - - devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); - } - - dev->board_ptr = a2150_boards + a2150_probe(dev); - dev->board_name = thisboard->name; - - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - /* analog input subdevice */ - s = dev->subdevices + 0; - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; - s->n_chan = 4; - s->len_chanlist = 4; - s->maxdata = 0xffff; - s->range_table = &range_a2150; - s->do_cmd = a2150_ai_cmd; - s->do_cmdtest = a2150_ai_cmdtest; - s->insn_read = a2150_ai_rinsn; - s->cancel = a2150_cancel; - - /* need to do this for software counting of completed conversions, to - * prevent hardware count from stopping acquisition */ - outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG); - - /* set card's irq and dma levels */ - outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); - - /* reset and sync adc clock circuitry */ - outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG); - outw_p(DPD_BIT, dev->iobase + CONFIG_REG); - /* initialize configuration register */ - devpriv->config_bits = 0; - outw(devpriv->config_bits, dev->iobase + CONFIG_REG); - /* wait until offset calibration is done, then enable analog inputs */ - for (i = 0; i < timeout; i++) { - if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0) - break; - udelay(1000); - } - if (i == timeout) { - printk - (" timed out waiting for offset calibration to complete\n"); - return -ETIME; - } - devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT; - outw(devpriv->config_bits, dev->iobase + CONFIG_REG); - - return 0; -}; - -static int a2150_detach(struct comedi_device *dev) -{ - printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name); - - /* only free stuff if it has been allocated by _attach */ - if (dev->iobase) { - /* put board in power-down mode */ - outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); - release_region(dev->iobase, A2150_SIZE); - } - - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (devpriv->dma) - free_dma(devpriv->dma); - kfree(devpriv->dma_buffer); - } - - return 0; -}; - static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { /* disable dma on card */ @@ -539,7 +351,10 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, if (err) return 1; - /* step 2: make sure trigger sources are unique and mutually compatible */ + /* + * step 2: make sure trigger sources are unique and mutually + * compatible + */ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) err++; @@ -771,7 +586,10 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* start acquisition for soft trigger */ outw(0, dev->iobase + FIFO_START_REG); - /* there is a 35.6 sample delay for data to get through the antialias filter */ + /* + * there is a 35.6 sample delay for data to get through the + * antialias filter + */ for (n = 0; n < filter_delay; n++) { for (i = 0; i < timeout; i++) { if (inw(dev->iobase + STATUS_REG) & FNE_BIT) @@ -812,8 +630,10 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } -/* sets bits in devpriv->clock_bits to nearest approximation of requested period, - * adjusts requested period to actual timing. */ +/* + * sets bits in devpriv->clock_bits to nearest approximation of requested + * period, adjusts requested period to actual timing. + */ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, int flags) { @@ -920,6 +740,162 @@ static int a2150_set_chanlist(struct comedi_device *dev, return 0; } +/* probes board type, returns offset */ +static int a2150_probe(struct comedi_device *dev) +{ + int status = inw(dev->iobase + STATUS_REG); + return ID_BITS(status); +} + +static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + unsigned long iobase = it->options[0]; + unsigned int irq = it->options[1]; + unsigned int dma = it->options[2]; + static const int timeout = 2000; + int i; + + printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name, + iobase); + if (irq) { + printk(", irq %u", irq); + } else { + printk(", no irq"); + } + if (dma) { + printk(", dma %u", dma); + } else { + printk(", no dma"); + } + printk("\n"); + + /* allocate and initialize dev->private */ + if (alloc_private(dev, sizeof(struct a2150_private)) < 0) + return -ENOMEM; + + if (iobase == 0) { + printk(" io base address required\n"); + return -EINVAL; + } + + /* check if io addresses are available */ + if (!request_region(iobase, A2150_SIZE, dev->driver->driver_name)) { + printk(" I/O port conflict\n"); + return -EIO; + } + dev->iobase = iobase; + + /* grab our IRQ */ + if (irq) { + /* check that irq is supported */ + if (irq < 3 || irq == 8 || irq == 13 || irq > 15) { + printk(" invalid irq line %u\n", irq); + return -EINVAL; + } + if (request_irq(irq, a2150_interrupt, 0, + dev->driver->driver_name, dev)) { + printk("unable to allocate irq %u\n", irq); + return -EINVAL; + } + devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); + dev->irq = irq; + } + /* initialize dma */ + if (dma) { + if (dma == 4 || dma > 7) { + printk(" invalid dma channel %u\n", dma); + return -EINVAL; + } + if (request_dma(dma, dev->driver->driver_name)) { + printk(" failed to allocate dma channel %u\n", dma); + return -EINVAL; + } + devpriv->dma = dma; + devpriv->dma_buffer = + kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); + if (devpriv->dma_buffer == NULL) + return -ENOMEM; + + disable_dma(dma); + set_dma_mode(dma, DMA_MODE_READ); + + devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); + } + + dev->board_ptr = a2150_boards + a2150_probe(dev); + dev->board_name = thisboard->name; + + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + /* analog input subdevice */ + s = dev->subdevices + 0; + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; + s->n_chan = 4; + s->len_chanlist = 4; + s->maxdata = 0xffff; + s->range_table = &range_a2150; + s->do_cmd = a2150_ai_cmd; + s->do_cmdtest = a2150_ai_cmdtest; + s->insn_read = a2150_ai_rinsn; + s->cancel = a2150_cancel; + + /* need to do this for software counting of completed conversions, to + * prevent hardware count from stopping acquisition */ + outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG); + + /* set card's irq and dma levels */ + outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); + + /* reset and sync adc clock circuitry */ + outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG); + outw_p(DPD_BIT, dev->iobase + CONFIG_REG); + /* initialize configuration register */ + devpriv->config_bits = 0; + outw(devpriv->config_bits, dev->iobase + CONFIG_REG); + /* wait until offset calibration is done, then enable analog inputs */ + for (i = 0; i < timeout; i++) { + if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0) + break; + udelay(1000); + } + if (i == timeout) { + printk + (" timed out waiting for offset calibration to complete\n"); + return -ETIME; + } + devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT; + outw(devpriv->config_bits, dev->iobase + CONFIG_REG); + + return 0; +}; + +static void a2150_detach(struct comedi_device *dev) +{ + if (dev->iobase) { + outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); + release_region(dev->iobase, A2150_SIZE); + } + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (devpriv->dma) + free_dma(devpriv->dma); + kfree(devpriv->dma_buffer); + } +}; + +static struct comedi_driver ni_at_a2150_driver = { + .driver_name = "ni_at_a2150", + .module = THIS_MODULE, + .attach = a2150_attach, + .detach = a2150_detach, +}; +module_comedi_driver(ni_at_a2150_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 138dcc2..c43dd8a 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -157,17 +157,6 @@ struct atao_board { int n_ao_chans; }; -static const struct atao_board atao_boards[] = { - { - .name = "ai-ao-6", - .n_ao_chans = 6, - }, - { - .name = "ai-ao-10", - .n_ao_chans = 10, - }, -}; - #define thisboard ((struct atao_board *)dev->board_ptr) struct atao_private { @@ -182,133 +171,6 @@ struct atao_private { #define devpriv ((struct atao_private *)dev->private) -static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int atao_detach(struct comedi_device *dev); -static struct comedi_driver driver_atao = { - .driver_name = "ni_at_ao", - .module = THIS_MODULE, - .attach = atao_attach, - .detach = atao_detach, - .board_name = &atao_boards[0].name, - .offset = sizeof(struct atao_board), - .num_names = ARRAY_SIZE(atao_boards), -}; - -static int __init driver_atao_init_module(void) -{ - return comedi_driver_register(&driver_atao); -} - -static void __exit driver_atao_cleanup_module(void) -{ - comedi_driver_unregister(&driver_atao); -} - -module_init(driver_atao_init_module); -module_exit(driver_atao_cleanup_module); - -static void atao_reset(struct comedi_device *dev); - -static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int atao_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int atao_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int atao_calib_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int atao_calib_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - int ao_unipolar; - - iobase = it->options[0]; - if (iobase == 0) - iobase = 0x1c0; - ao_unipolar = it->options[3]; - - printk(KERN_INFO "comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase); - - if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) { - printk(" I/O port conflict\n"); - return -EIO; - } - dev->iobase = iobase; - - /* dev->board_ptr = atao_probe(dev); */ - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct atao_private)) < 0) - return -ENOMEM; - - if (alloc_subdevices(dev, 4) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->n_ao_chans; - s->maxdata = (1 << 12) - 1; - if (ao_unipolar) - s->range_table = &range_unipolar10; - else - s->range_table = &range_bipolar10; - s->insn_write = &atao_ao_winsn; - s->insn_read = &atao_ao_rinsn; - - s = dev->subdevices + 1; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = atao_dio_insn_bits; - s->insn_config = atao_dio_insn_config; - - s = dev->subdevices + 2; - /* caldac subdevice */ - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 21; - s->maxdata = 0xff; - s->insn_read = atao_calib_insn_read; - s->insn_write = atao_calib_insn_write; - - s = dev->subdevices + 3; - /* eeprom subdevice */ - /* s->type=COMEDI_SUBD_EEPROM; */ - s->type = COMEDI_SUBD_UNUSED; - - atao_reset(dev); - - printk(KERN_INFO "\n"); - - return 0; -} - -static int atao_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: atao: remove\n", dev->minor); - - if (dev->iobase) - release_region(dev->iobase, ATAO_SIZE); - - return 0; -} - static void atao_reset(struct comedi_device *dev) { /* This is the reset sequence described in the manual */ @@ -471,6 +333,106 @@ static int atao_calib_insn_write(struct comedi_device *dev, return insn->n; } +static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + unsigned long iobase; + int ao_unipolar; + + iobase = it->options[0]; + if (iobase == 0) + iobase = 0x1c0; + ao_unipolar = it->options[3]; + + printk(KERN_INFO "comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase); + + if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) { + printk(" I/O port conflict\n"); + return -EIO; + } + dev->iobase = iobase; + + /* dev->board_ptr = atao_probe(dev); */ + + dev->board_name = thisboard->name; + + if (alloc_private(dev, sizeof(struct atao_private)) < 0) + return -ENOMEM; + + if (alloc_subdevices(dev, 4) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->n_ao_chans; + s->maxdata = (1 << 12) - 1; + if (ao_unipolar) + s->range_table = &range_unipolar10; + else + s->range_table = &range_bipolar10; + s->insn_write = &atao_ao_winsn; + s->insn_read = &atao_ao_rinsn; + + s = dev->subdevices + 1; + /* digital i/o subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = atao_dio_insn_bits; + s->insn_config = atao_dio_insn_config; + + s = dev->subdevices + 2; + /* caldac subdevice */ + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 21; + s->maxdata = 0xff; + s->insn_read = atao_calib_insn_read; + s->insn_write = atao_calib_insn_write; + + s = dev->subdevices + 3; + /* eeprom subdevice */ + /* s->type=COMEDI_SUBD_EEPROM; */ + s->type = COMEDI_SUBD_UNUSED; + + atao_reset(dev); + + printk(KERN_INFO "\n"); + + return 0; +} + +static void atao_detach(struct comedi_device *dev) +{ + if (dev->iobase) + release_region(dev->iobase, ATAO_SIZE); +} + +static const struct atao_board atao_boards[] = { + { + .name = "ai-ao-6", + .n_ao_chans = 6, + }, { + .name = "ai-ao-10", + .n_ao_chans = 10, + }, +}; + +static struct comedi_driver ni_at_ao_driver = { + .driver_name = "ni_at_ao", + .module = THIS_MODULE, + .attach = atao_attach, + .detach = atao_detach, + .board_name = &atao_boards[0].name, + .offset = sizeof(struct atao_board), + .num_names = ARRAY_SIZE(atao_boards), +}; +module_comedi_driver(ni_at_ao_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 647c228..6448373 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -343,49 +343,8 @@ static struct pnp_device_id device_ids[] = { MODULE_DEVICE_TABLE(pnp, device_ids); -static int ni_atmio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int ni_atmio_detach(struct comedi_device *dev); -static struct comedi_driver driver_atmio = { - .driver_name = "ni_atmio", - .module = THIS_MODULE, - .attach = ni_atmio_attach, - .detach = ni_atmio_detach, -}; - -static int __init driver_atmio_init_module(void) -{ - return comedi_driver_register(&driver_atmio); -} - -static void __exit driver_atmio_cleanup_module(void) -{ - comedi_driver_unregister(&driver_atmio); -} - -module_init(driver_atmio_init_module); -module_exit(driver_atmio_cleanup_module); - #include "ni_mio_common.c" -static int ni_getboardtype(struct comedi_device *dev); - -/* clean up allocated resources */ -static int ni_atmio_detach(struct comedi_device *dev) -{ - mio_common_detach(dev); - - if (dev->iobase) - release_region(dev->iobase, NI_SIZE); - if (dev->irq) - free_irq(dev->irq, dev); - - if (devpriv->isapnp_dev) - pnp_device_detach(devpriv->isapnp_dev); - - return 0; -} - static int ni_isapnp_find_board(struct pnp_dev **dev) { struct pnp_dev *isapnp_dev = NULL; @@ -424,6 +383,26 @@ static int ni_isapnp_find_board(struct pnp_dev **dev) return 0; } +static int ni_getboardtype(struct comedi_device *dev) +{ + int device_id = ni_read_eeprom(dev, 511); + int i; + + for (i = 0; i < n_ni_boards; i++) { + if (ni_boards[i].device_id == device_id) + return i; + + } + if (device_id == 255) + printk(" can't find board\n"); + else if (device_id == 0) + printk(" EEPROM read error (?) or device not found\n"); + else + printk(" unknown device ID %d -- contact author\n", device_id); + + return -1; +} + static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -518,22 +497,21 @@ static int ni_atmio_attach(struct comedi_device *dev, return 0; } -static int ni_getboardtype(struct comedi_device *dev) +static void ni_atmio_detach(struct comedi_device *dev) { - int device_id = ni_read_eeprom(dev, 511); - int i; - - for (i = 0; i < n_ni_boards; i++) { - if (ni_boards[i].device_id == device_id) - return i; - - } - if (device_id == 255) - printk(" can't find board\n"); - else if (device_id == 0) - printk(" EEPROM read error (?) or device not found\n"); - else - printk(" unknown device ID %d -- contact author\n", device_id); - - return -1; + mio_common_detach(dev); + if (dev->iobase) + release_region(dev->iobase, NI_SIZE); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv->isapnp_dev) + pnp_device_detach(devpriv->isapnp_dev); } + +static struct comedi_driver ni_atmio_driver = { + .driver_name = "ni_atmio", + .module = THIS_MODULE, + .attach = ni_atmio_attach, + .detach = ni_atmio_detach, +}; +module_comedi_driver(ni_atmio_driver); diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 285b933..4f61453 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -110,60 +110,8 @@ struct atmio16_board_t { int has_8255; }; -static const struct atmio16_board_t atmio16_boards[] = { - { - .name = "atmio16", - .has_8255 = 0, - }, - { - .name = "atmio16d", - .has_8255 = 1, - }, -}; - -#define n_atmio16_boards ARRAY_SIZE(atmio16_boards) - #define boardtype ((const struct atmio16_board_t *)dev->board_ptr) -/* function prototypes */ -static int atmio16d_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int atmio16d_detach(struct comedi_device *dev); -static irqreturn_t atmio16d_interrupt(int irq, void *d); -static int atmio16d_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int atmio16d_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s); -static int atmio16d_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); -static void reset_counters(struct comedi_device *dev); -static void reset_atmio16d(struct comedi_device *dev); - -/* main driver struct */ -static struct comedi_driver driver_atmio16d = { - .driver_name = "atmio16", - .module = THIS_MODULE, - .attach = atmio16d_attach, - .detach = atmio16d_detach, - .board_name = &atmio16_boards[0].name, - .num_names = n_atmio16_boards, - .offset = sizeof(struct atmio16_board_t), -}; - -static int __init driver_atmio16d_init_module(void) -{ - return comedi_driver_register(&driver_atmio16d); -} - -static void __exit driver_atmio16d_cleanup_module(void) -{ - comedi_driver_unregister(&driver_atmio16d); -} - -module_init(driver_atmio16d_init_module); -module_exit(driver_atmio16d_cleanup_module); - /* range structs */ static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, { BIP_RANGE @@ -881,24 +829,38 @@ static int atmio16d_attach(struct comedi_device *dev, return 0; } -static int atmio16d_detach(struct comedi_device *dev) +static void atmio16d_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: atmio16d: remove\n", dev->minor); - if (dev->subdevices && boardtype->has_8255) subdev_8255_cleanup(dev, dev->subdevices + 3); - if (dev->irq) free_irq(dev->irq, dev); - reset_atmio16d(dev); - if (dev->iobase) release_region(dev->iobase, ATMIO16D_SIZE); - - return 0; } +static const struct atmio16_board_t atmio16_boards[] = { + { + .name = "atmio16", + .has_8255 = 0, + }, { + .name = "atmio16d", + .has_8255 = 1, + }, +}; + +static struct comedi_driver atmio16d_driver = { + .driver_name = "atmio16", + .module = THIS_MODULE, + .attach = atmio16d_attach, + .detach = atmio16d_detach, + .board_name = &atmio16_boards[0].name, + .num_names = ARRAY_SIZE(atmio16_boards), + .offset = sizeof(struct atmio16_board_t), +}; +module_comedi_driver(atmio16d_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index e242012..75764e8 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -57,7 +57,7 @@ static struct pcmcia_device *pcmcia_cur_dev; static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dio700_detach(struct comedi_device *dev); +static void dio700_detach(struct comedi_device *dev); enum dio700_bustype { pcmcia_bustype }; @@ -419,19 +419,14 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; }; -static int dio700_detach(struct comedi_device *dev) +static void dio700_detach(struct comedi_device *dev) { - printk(KERN_ERR "comedi%d: ni_daq_700: cs-remove\n", dev->minor); - if (dev->subdevices) subdev_700_cleanup(dev, dev->subdevices + 0); - if (thisboard->bustype != pcmcia_bustype && dev->iobase) release_region(dev->iobase, DIO700_SIZE); if (dev->irq) free_irq(dev->irq, dev); - - return 0; }; static void dio700_config(struct pcmcia_device *link); @@ -472,18 +467,12 @@ static int dio700_cs_attach(struct pcmcia_device *link) static void dio700_cs_detach(struct pcmcia_device *link) { - - printk(KERN_INFO "ni_daq_700: cs-detach!\n"); - - dev_dbg(&link->dev, "dio700_cs_detach\n"); - ((struct local_info_t *)link->priv)->stop = 1; dio700_release(link); /* This points to the parent struct local_info_t struct */ kfree(link->priv); - -} /* dio700_cs_detach */ +} static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index c0423a8..493a227 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -57,7 +57,7 @@ static struct pcmcia_device *pcmcia_cur_dev; #define DIO24_SIZE 4 /* size of io region used by board */ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dio24_detach(struct comedi_device *dev); +static void dio24_detach(struct comedi_device *dev); enum dio24_bustype { pcmcia_bustype }; @@ -168,19 +168,14 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; }; -static int dio24_detach(struct comedi_device *dev) +static void dio24_detach(struct comedi_device *dev) { - dev_info(dev->hw_dev, "comedi%d: ni_daq_dio24: remove\n", dev->minor); - if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 0); - if (thisboard->bustype != pcmcia_bustype && dev->iobase) release_region(dev->iobase, DIO24_SIZE); if (dev->irq) free_irq(dev->irq, dev); - - return 0; }; static void dio24_config(struct pcmcia_device *link); @@ -221,18 +216,12 @@ static int dio24_cs_attach(struct pcmcia_device *link) static void dio24_cs_detach(struct pcmcia_device *link) { - - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n"); - - dev_dbg(&link->dev, "dio24_cs_detach\n"); - ((struct local_info_t *)link->priv)->stop = 1; dio24_release(link); /* This points to the parent local_info_t struct */ kfree(link->priv); - -} /* dio24_cs_detach */ +} static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 721b2be..5334977 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -805,13 +805,10 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot) } #endif -int labpc_common_detach(struct comedi_device *dev) +void labpc_common_detach(struct comedi_device *dev) { - printk(KERN_ERR "comedi%d: ni_labpc: detach\n", dev->minor); - if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 2); - #ifdef CONFIG_ISA_DMA_API /* only free stuff if it has been allocated by _attach */ kfree(devpriv->dma_buffer); @@ -826,8 +823,6 @@ int labpc_common_detach(struct comedi_device *dev) if (devpriv->mite) mite_unsetup(devpriv->mite); #endif - - return 0; }; EXPORT_SYMBOL_GPL(labpc_common_detach); @@ -2141,7 +2136,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, static int __devinit driver_labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_labpc.driver_name); + return comedi_pci_auto_config(dev, &driver_labpc); } static void __devexit driver_labpc_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index 422cee5..e052ed3 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -103,7 +103,7 @@ struct labpc_private { int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, unsigned int irq, unsigned int dma); -int labpc_common_detach(struct comedi_device *dev); +void labpc_common_detach(struct comedi_device *dev); extern const int labpc_1200_is_unipolar[]; extern const int labpc_1200_ai_gain_bits[]; diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index ff38405..dbb61b6 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -188,21 +188,13 @@ static int labpc_cs_attach(struct pcmcia_device *link) static void labpc_cs_detach(struct pcmcia_device *link) { - dev_dbg(&link->dev, "labpc_cs_detach\n"); - - /* - If the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ ((struct local_info_t *)link->priv)->stop = 1; labpc_release(link); /* This points to the parent local_info_t struct (may be null) */ kfree(link->priv); -} /* labpc_cs_detach */ +} static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 53ec24bb..b85765d 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -227,7 +227,7 @@ static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr) static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int mio_cs_detach(struct comedi_device *dev); +static void mio_cs_detach(struct comedi_device *dev); static struct comedi_driver driver_ni_mio_cs = { .driver_name = "ni_mio_cs", .module = THIS_MODULE, @@ -240,18 +240,11 @@ static struct comedi_driver driver_ni_mio_cs = { static int ni_getboardtype(struct comedi_device *dev, struct pcmcia_device *link); -/* clean up allocated resources */ -/* called when driver is removed */ -static int mio_cs_detach(struct comedi_device *dev) +static void mio_cs_detach(struct comedi_device *dev) { mio_common_detach(dev); - - /* PCMCIA layer frees the IO region */ - if (dev->irq) free_irq(dev->irq, dev); - - return 0; } static void mio_cs_config(struct pcmcia_device *link); @@ -276,8 +269,6 @@ static void cs_release(struct pcmcia_device *link) static void cs_detach(struct pcmcia_device *link) { - DPRINTK("cs_detach(link=%p)\n", link); - cs_release(link); } diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 1df8fcb..37b7008 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -293,18 +293,9 @@ enum FPGA_Control_Bits { #define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC) #endif -static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int nidio_detach(struct comedi_device *dev); static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static struct comedi_driver driver_pcidio = { - .driver_name = "ni_pcidio", - .module = THIS_MODULE, - .attach = nidio_attach, - .detach = nidio_detach, -}; - struct nidio_board { int dev_id; @@ -381,22 +372,6 @@ static const struct nidio_board nidio_boards[] = { #define n_nidio_boards ARRAY_SIZE(nidio_boards) #define this_board ((const struct nidio_board *)dev->board_ptr) -static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); - struct nidio96_private { struct mite_struct *mite; int boardtype; @@ -414,7 +389,6 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int ni_pcidio_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum); -static int nidio_find_device(struct comedi_device *dev, int bus, int slot); static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode); static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s); @@ -1205,6 +1179,33 @@ static int pci_6534_upload_firmware(struct comedi_device *dev, int options[]) return 0; } +static int nidio_find_device(struct comedi_device *dev, int bus, int slot) +{ + struct mite_struct *mite; + int i; + + for (mite = mite_devices; mite; mite = mite->next) { + if (mite->used) + continue; + if (bus || slot) { + if (bus != mite->pcidev->bus->number || + slot != PCI_SLOT(mite->pcidev->devfn)) + continue; + } + for (i = 0; i < n_nidio_boards; i++) { + if (mite_device_id(mite) == nidio_boards[i].dev_id) { + dev->board_ptr = nidio_boards + i; + devpriv->mite = mite; + + return 0; + } + } + } + printk(KERN_WARNING "no device found\n"); + mite_list_devices(); + return -EIO; +} + static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; @@ -1306,7 +1307,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int nidio_detach(struct comedi_device *dev) +static void nidio_detach(struct comedi_device *dev) { int i; @@ -1314,10 +1315,8 @@ static int nidio_detach(struct comedi_device *dev) for (i = 0; i < this_board->n_8255; i++) subdev_8255_cleanup(dev, dev->subdevices + i); } - if (dev->irq) free_irq(dev->irq, dev); - if (devpriv) { if (devpriv->di_mite_ring) { mite_free_ring(devpriv->di_mite_ring); @@ -1326,73 +1325,48 @@ static int nidio_detach(struct comedi_device *dev) if (devpriv->mite) mite_unsetup(devpriv->mite); } - return 0; } -static int nidio_find_device(struct comedi_device *dev, int bus, int slot) -{ - struct mite_struct *mite; - int i; - - for (mite = mite_devices; mite; mite = mite->next) { - if (mite->used) - continue; - if (bus || slot) { - if (bus != mite->pcidev->bus->number || - slot != PCI_SLOT(mite->pcidev->devfn)) - continue; - } - for (i = 0; i < n_nidio_boards; i++) { - if (mite_device_id(mite) == nidio_boards[i].dev_id) { - dev->board_ptr = nidio_boards + i; - devpriv->mite = mite; - - return 0; - } - } - } - printk(KERN_WARNING "no device found\n"); - mite_list_devices(); - return -EIO; -} +static struct comedi_driver ni_pcidio_driver = { + .driver_name = "ni_pcidio", + .module = THIS_MODULE, + .attach = nidio_attach, + .detach = nidio_detach, +}; -static int __devinit driver_pcidio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static int __devinit ni_pcidio_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_pcidio.driver_name); + return comedi_pci_auto_config(dev, &ni_pcidio_driver); } -static void __devexit driver_pcidio_pci_remove(struct pci_dev *dev) +static void __devexit ni_pcidio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_pcidio_pci_driver = { - .id_table = ni_pcidio_pci_table, - .probe = &driver_pcidio_pci_probe, - .remove = __devexit_p(&driver_pcidio_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table); -static int __init driver_pcidio_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pcidio); - if (retval < 0) - return retval; - - driver_pcidio_pci_driver.name = (char *)driver_pcidio.driver_name; - return pci_register_driver(&driver_pcidio_pci_driver); -} - -static void __exit driver_pcidio_cleanup_module(void) -{ - pci_unregister_driver(&driver_pcidio_pci_driver); - comedi_driver_unregister(&driver_pcidio); -} - -module_init(driver_pcidio_init_module); -module_exit(driver_pcidio_cleanup_module); +static struct pci_driver ni_pcidio_pci_driver = { + .name = "ni_pcidio", + .id_table = ni_pcidio_pci_table, + .probe = ni_pcidio_pci_probe, + .remove = __devexit_p(ni_pcidio_pci_remove), +}; +module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 27baefa..3974c0d 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -129,66 +129,6 @@ Bugs: #define DRV_NAME "ni_pcimio" -/* The following two tables must be in the same order */ -static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0162)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1170)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1180)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1190)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11b0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11c0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11d0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1270)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1330)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1340)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1350)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14e0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14f0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1580)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x15b0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1880)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1870)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18b0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18c0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2410)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2420)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2430)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2890)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x28c0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a60)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a70)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a80)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ab0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b80)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b90)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c80)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ca0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70aa)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ab)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ac)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70af)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b4)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b6)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b7)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b8)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bc)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bd)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bf)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c0)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70f2)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x710d)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716c)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716d)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni_pci_table); - /* These are not all the possible ao ranges for 628x boards. They can do OFFSET +- REFERENCE where OFFSET can be 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can @@ -1250,54 +1190,6 @@ static const struct ni_board_struct ni_boards[] = { #define n_pcimio_boards ARRAY_SIZE(ni_boards) -static int pcimio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcimio_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcimio = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = pcimio_attach, - .detach = pcimio_detach, -}; - -static int __devinit driver_pcimio_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_pcimio.driver_name); -} - -static void __devexit driver_pcimio_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_pcimio_pci_driver = { - .id_table = ni_pci_table, - .probe = &driver_pcimio_pci_probe, - .remove = __devexit_p(&driver_pcimio_pci_remove) -}; - -static int __init driver_pcimio_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_pcimio); - if (retval < 0) - return retval; - - driver_pcimio_pci_driver.name = (char *)driver_pcimio.driver_name; - return pci_register_driver(&driver_pcimio_pci_driver); -} - -static void __exit driver_pcimio_cleanup_module(void) -{ - pci_unregister_driver(&driver_pcimio_pci_driver); - comedi_driver_unregister(&driver_pcimio); -} - -module_init(driver_pcimio_init_module); -module_exit(driver_pcimio_cleanup_module); - struct ni_private { NI_PRIVATE_COMMON}; #define devpriv ((struct ni_private *)dev->private) @@ -1681,13 +1573,11 @@ static void init_6143(struct comedi_device *dev) ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143); } -/* cleans up allocated resources */ -static int pcimio_detach(struct comedi_device *dev) +static void pcimio_detach(struct comedi_device *dev) { mio_common_detach(dev); if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { mite_free_ring(devpriv->ai_mite_ring); mite_free_ring(devpriv->ao_mite_ring); @@ -1697,8 +1587,6 @@ static int pcimio_detach(struct comedi_device *dev) if (devpriv->mite) mite_unsetup(devpriv->mite); } - - return 0; } static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -1874,6 +1762,90 @@ static int pcimio_dio_change(struct comedi_device *dev, return 0; } +static struct comedi_driver ni_pcimio_driver = { + .driver_name = "ni_pcimio", + .module = THIS_MODULE, + .attach = pcimio_attach, + .detach = pcimio_detach, +}; + +static int __devinit ni_pcimio_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &ni_pcimio_driver); +} + +static void __devexit ni_pcimio_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0162) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1170) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1180) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1190) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11b0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11c0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x11d0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1270) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1330) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1340) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1350) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14e0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x14f0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1580) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x15b0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1880) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1870) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18b0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x18c0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2410) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2420) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2430) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2890) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x28c0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a60) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a70) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2a80) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ab0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b80) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b90) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c80) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2ca0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70aa) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ab) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70ac) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70af) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b4) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b6) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b7) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70b8) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bc) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bd) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70bf) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70c0) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x70f2) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x710d) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716c) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x716d) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d) }, + { PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table); + +static struct pci_driver ni_pcimio_pci_driver = { + .name = "ni_pcimio", + .id_table = ni_pcimio_pci_table, + .probe = ni_pcimio_pci_probe, + .remove = __devexit_p(ni_pcimio_pci_remove) +}; +module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver) + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index c4ca537..5e00212 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -362,8 +362,8 @@ static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index) return 0; } -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int - counter_index) +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg( + int counter_index) { switch (counter_index) { case 0: @@ -407,8 +407,8 @@ static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index) return 0; } -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int - counter_index) +static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg( + int counter_index) { switch (counter_index) { case 0: @@ -472,15 +472,22 @@ enum Gi_Counting_Mode_Reg_Bits { Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift, Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift, Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift, - Gi_HW_Arm_Enable_Bit = 0x80, /* from m-series example code, not documented in 660x register level manual */ - Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, /* from m-series example code, not documented in 660x register level manual */ + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_HW_Arm_Enable_Bit = 0x80, + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, Gi_660x_Prescale_X8_Bit = 0x1000, Gi_M_Series_Prescale_X8_Bit = 0x2000, Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift, - /* must be set for clocks over 40MHz, which includes synchronous counting and quadrature modes */ + /* must be set for clocks over 40MHz, which includes synchronous + * counting and quadrature modes */ Gi_660x_Alternate_Sync_Bit = 0x2000, Gi_M_Series_Alternate_Sync_Bit = 0x4000, - Gi_660x_Prescale_X2_Bit = 0x4000, /* from m-series example code, not documented in 660x register level manual */ + /* from m-series example code, not documented in 660x register level + * manual */ + Gi_660x_Prescale_X2_Bit = 0x4000, Gi_M_Series_Prescale_X2_Bit = 0x8000, }; @@ -503,7 +510,8 @@ enum Gi_Mode_Bits { Gi_Level_Gating_Bits = 0x1, Gi_Rising_Edge_Gating_Bits = 0x2, Gi_Falling_Edge_Gating_Bits = 0x3, - Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with rising edge gating mode */ + Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with + * rising edge gating mode */ Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18, Gi_Edge_Gate_Starts_Stops_Bits = 0x0, Gi_Edge_Gate_Stops_Starts_Bits = 0x8, @@ -686,11 +694,10 @@ static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index) { unsigned bit; - if (counter_index % 2) { + if (counter_index % 2) bit = G1_Gate_Interrupt_Enable_Bit; - } else { + else bit = G0_Gate_Interrupt_Enable_Bit; - } return bit; } @@ -748,8 +755,9 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, } /* ni_tio_set_bits( ) is for safely writing to registers whose bits may be -twiddled in interrupt context, or whose software copy may be read in interrupt context. -*/ + * twiddled in interrupt context, or whose software copy may be read in + * interrupt context. + */ static inline void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register register_index, unsigned bit_mask, unsigned bit_values) diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index b44386a..2e7753f 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -148,42 +148,8 @@ struct pcl711_board { const struct comedi_lrange *ai_range_type; }; -static const struct pcl711_board boardtypes[] = { - {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5}, - {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai}, - {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai}, - {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl711_board)) #define this_board ((const struct pcl711_board *)dev->board_ptr) -static int pcl711_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl711_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcl711 = { - .driver_name = "pcl711", - .module = THIS_MODULE, - .attach = pcl711_attach, - .detach = pcl711_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl711_board), -}; - -static int __init driver_pcl711_init_module(void) -{ - return comedi_driver_register(&driver_pcl711); -} - -static void __exit driver_pcl711_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl711); -} - -module_init(driver_pcl711_init_module); -module_exit(driver_pcl711_cleanup_module); - struct pcl711_private { int board; @@ -513,21 +479,6 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, return 2; } -/* Free any resources that we have claimed */ -static int pcl711_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: pcl711: remove\n", dev->minor); - - if (dev->irq) - free_irq(dev->irq, dev); - - if (dev->iobase) - release_region(dev->iobase, PCL711_SIZE); - - return 0; -} - -/* Initialization */ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -640,6 +591,32 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } +static void pcl711_detach(struct comedi_device *dev) +{ + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->iobase) + release_region(dev->iobase, PCL711_SIZE); +} + +static const struct pcl711_board boardtypes[] = { + { "pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5 }, + { "pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai }, + { "acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai }, + { "acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai }, +}; + +static struct comedi_driver pcl711_driver = { + .driver_name = "pcl711", + .module = THIS_MODULE, + .attach = pcl711_attach, + .detach = pcl711_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl711_board), +}; +module_comedi_driver(pcl711_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 61b075d..1f66fe1 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -56,10 +56,6 @@ See the source for configuration details. /* #define PCL724_IRQ 1 no IRQ support now */ -static int pcl724_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl724_detach(struct comedi_device *dev); - struct pcl724_board { const char *name; /* board name */ @@ -71,41 +67,8 @@ struct pcl724_board { char is_pet48; }; -static const struct pcl724_board boardtypes[] = { - {"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,}, - {"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0,}, - {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0,}, - {"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0,}, - {"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,}, - {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl724_board)) #define this_board ((const struct pcl724_board *)dev->board_ptr) -static struct comedi_driver driver_pcl724 = { - .driver_name = "pcl724", - .module = THIS_MODULE, - .attach = pcl724_attach, - .detach = pcl724_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl724_board), -}; - -static int __init driver_pcl724_init_module(void) -{ - return comedi_driver_register(&driver_pcl724); -} - -static void __exit driver_pcl724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl724); -} - -module_init(driver_pcl724_init_module); -module_exit(driver_pcl724_cleanup_module); - static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; @@ -214,25 +177,39 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int pcl724_detach(struct comedi_device *dev) +static void pcl724_detach(struct comedi_device *dev) { int i; - /* printk("comedi%d: pcl724: remove\n",dev->minor); */ - for (i = 0; i < dev->n_subdevices; i++) subdev_8255_cleanup(dev, dev->subdevices + i); - #ifdef PCL724_IRQ if (dev->irq) free_irq(dev->irq, dev); #endif - release_region(dev->iobase, this_board->io_range); - - return 0; } +static const struct pcl724_board boardtypes[] = { + { "pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, }, + { "pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0, }, + { "pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0, }, + { "acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0, }, + { "acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0, }, + { "pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1, }, +}; + +static struct comedi_driver pcl724_driver = { + .driver_name = "pcl724", + .module = THIS_MODULE, + .attach = pcl724_attach, + .detach = pcl724_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl724_board), +}; +module_comedi_driver(pcl724_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c index 24b223c..83a6fa5 100644 --- a/drivers/staging/comedi/drivers/pcl725.c +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -20,29 +20,6 @@ Devices: [Advantech] PCL-725 (pcl725) #define PCL725_DO 0 #define PCL725_DI 1 -static int pcl725_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl725_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcl725 = { - .driver_name = "pcl725", - .module = THIS_MODULE, - .attach = pcl725_attach, - .detach = pcl725_detach, -}; - -static int __init driver_pcl725_init_module(void) -{ - return comedi_driver_register(&driver_pcl725); -} - -static void __exit driver_pcl725_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl725); -} - -module_init(driver_pcl725_init_module); -module_exit(driver_pcl725_cleanup_module); - static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -112,16 +89,20 @@ static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int pcl725_detach(struct comedi_device *dev) +static void pcl725_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pcl725: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, PCL725_SIZE); - - return 0; } +static struct comedi_driver pcl725_driver = { + .driver_name = "pcl725", + .module = THIS_MODULE, + .attach = pcl725_attach, + .detach = pcl725_detach, +}; +module_comedi_driver(pcl725_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 897cd80..d25c30c 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -111,10 +111,6 @@ static const struct comedi_lrange *const rangelist_728[] = { &range_4_20mA, &range_0_20mA }; -static int pcl726_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl726_detach(struct comedi_device *dev); - struct pcl726_board { const char *name; /* driver name */ @@ -149,32 +145,8 @@ static const struct pcl726_board boardtypes[] = { &rangelist_728[0],}, }; -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board)) #define this_board ((const struct pcl726_board *)dev->board_ptr) -static struct comedi_driver driver_pcl726 = { - .driver_name = "pcl726", - .module = THIS_MODULE, - .attach = pcl726_attach, - .detach = pcl726_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl726_board), -}; - -static int __init driver_pcl726_init_module(void) -{ - return comedi_driver_register(&driver_pcl726); -} - -static void __exit driver_pcl726_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl726); -} - -module_init(driver_pcl726_init_module); -module_exit(driver_pcl726_cleanup_module); - struct pcl726_private { int bipolar[12]; @@ -378,21 +350,27 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int pcl726_detach(struct comedi_device *dev) +static void pcl726_detach(struct comedi_device *dev) { -/* printk("comedi%d: pcl726: remove\n",dev->minor); */ - #ifdef ACL6126_IRQ if (dev->irq) free_irq(dev->irq, dev); #endif - if (dev->iobase) release_region(dev->iobase, this_board->io_range); - - return 0; } +static struct comedi_driver pcl726_driver = { + .driver_name = "pcl726", + .module = THIS_MODULE, + .attach = pcl726_attach, + .detach = pcl726_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl726_board), +}; +module_comedi_driver(pcl726_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index c9682d6..e11704a 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -26,48 +26,14 @@ The ACL-7130 card have an 8254 timer/counter not supported by this driver. #define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */ #define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */ -static int pcl730_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl730_detach(struct comedi_device *dev); - struct pcl730_board { const char *name; /* board name */ unsigned int io_range; /* len of I/O space */ }; -static const struct pcl730_board boardtypes[] = { - {"pcl730", PCL730_SIZE,}, - {"iso730", PCL730_SIZE,}, - {"acl7130", ACL7130_SIZE,}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl730_board)) #define this_board ((const struct pcl730_board *)dev->board_ptr) -static struct comedi_driver driver_pcl730 = { - .driver_name = "pcl730", - .module = THIS_MODULE, - .attach = pcl730_attach, - .detach = pcl730_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl730_board), -}; - -static int __init driver_pcl730_init_module(void) -{ - return comedi_driver_register(&driver_pcl730); -} - -static void __exit driver_pcl730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl730); -} - -module_init(driver_pcl730_init_module); -module_exit(driver_pcl730_cleanup_module); - static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -168,16 +134,29 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int pcl730_detach(struct comedi_device *dev) +static void pcl730_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pcl730: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, this_board->io_range); - - return 0; } +static const struct pcl730_board boardtypes[] = { + { "pcl730", PCL730_SIZE, }, + { "iso730", PCL730_SIZE, }, + { "acl7130", ACL7130_SIZE, }, +}; + +static struct comedi_driver pcl730_driver = { + .driver_name = "pcl730", + .module = THIS_MODULE, + .attach = pcl730_attach, + .detach = pcl730_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl730_board), +}; +module_comedi_driver(pcl730_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 6fc7464..51f4ca9 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -316,10 +316,6 @@ static const struct comedi_lrange range_a821pgh_ai = { 4, { } }; -static int pcl812_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl812_detach(struct comedi_device *dev); - struct pcl812_board { const char *name; /* board name */ @@ -340,89 +336,8 @@ struct pcl812_board { unsigned char haveMPC508; /* 1=board use MPC508A multiplexor */ }; -static const struct pcl812_board boardtypes[] = { - {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff, - 33000, 500, &range_bipolar10, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, - 33000, 500, &range_pcl812pg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, - 10000, 500, &range_pcl812pg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff, - 10000, 500, &range_pcl813b_ai, &range_unipolar5, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff, - 10000, 500, &range_pcl813b_ai, NULL, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff, - 10000, 500, &range_a821pgh_ai, &range_unipolar5, - 0x000c, 0x00, PCLx1x_IORANGE, 0}, - {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 10000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 8000, 500, &range_acl8112dg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, - 8000, 500, &range_acl8112hg_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, - {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_pcl813b_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_pcl813b_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_acl8113_1_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff, - 0, 0, &range_iso813_1_ai, NULL, - 0x0000, 0x00, PCLx1x_IORANGE, 0}, - {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff, - 10000, 500, &range_pcl813b2_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, - {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff, - 10000, 500, &range_pcl813b2_ai, &range_unipolar5, - 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board)) #define this_board ((const struct pcl812_board *)dev->board_ptr) -static struct comedi_driver driver_pcl812 = { - .driver_name = "pcl812", - .module = THIS_MODULE, - .attach = pcl812_attach, - .detach = pcl812_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl812_board), -}; - -static int __init driver_pcl812_init_module(void) -{ - return comedi_driver_register(&driver_pcl812); -} - -static void __exit driver_pcl812_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl812); -} - -module_init(driver_pcl812_init_module); -module_exit(driver_pcl812_cleanup_module); - struct pcl812_private { unsigned char valid; /* =1 device is OK */ @@ -1356,9 +1271,6 @@ static void pcl812_reset(struct comedi_device *dev) #endif } -/* -============================================================================== -*/ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret, subdev; @@ -1702,19 +1614,79 @@ no_dma: return 0; } -/* -============================================================================== - */ -static int pcl812_detach(struct comedi_device *dev) +static void pcl812_detach(struct comedi_device *dev) { - -#ifdef PCL812_EXTDEBUG - printk(KERN_DEBUG "comedi%d: pcl812: remove\n", dev->minor); -#endif free_resources(dev); - return 0; } +static const struct pcl812_board boardtypes[] = { + {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff, + 33000, 500, &range_bipolar10, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, + 33000, 500, &range_pcl812pg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff, + 10000, 500, &range_pcl812pg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff, + 10000, 500, &range_pcl813b_ai, &range_unipolar5, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff, + 10000, 500, &range_pcl813b_ai, NULL, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff, + 10000, 500, &range_a821pgh_ai, &range_unipolar5, + 0x000c, 0x00, PCLx1x_IORANGE, 0}, + {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 10000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 8000, 500, &range_acl8112dg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff, + 8000, 500, &range_acl8112hg_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, + {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_pcl813b_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_pcl813b_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_acl8113_1_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff, + 0, 0, &range_iso813_1_ai, NULL, + 0x0000, 0x00, PCLx1x_IORANGE, 0}, + {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff, + 10000, 500, &range_pcl813b2_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 1}, + {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff, + 10000, 500, &range_pcl813b2_ai, &range_unipolar5, + 0xdcfc, 0x0a, PCLx1x_IORANGE, 0}, +}; + +static struct comedi_driver pcl812_driver = { + .driver_name = "pcl812", + .module = THIS_MODULE, + .attach = pcl812_attach, + .detach = pcl812_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl812_board), +}; +module_comedi_driver(pcl812_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 96cd7ec..cc67b6d 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -125,63 +125,14 @@ struct pcl816_board { int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; -static const struct pcl816_board boardtypes[] = { - {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, - &range_pcl816, PCLx1x_RANGE, - 0x00fc, /* IRQ mask */ - 0x0a, /* DMA mask */ - 0xffff, /* 16-bit card */ - 0xffff, /* D/A maxdata */ - 1024, - 1, /* ao chan list */ - 100}, - {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, - &range_pcl816, PCLx1x_RANGE, - 0x00fc, - 0x0a, - 0x3fff, /* 14 bit card */ - 0x3fff, - 1024, - 1, - 100}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board)) #define devpriv ((struct pcl816_private *)dev->private) #define this_board ((const struct pcl816_board *)dev->board_ptr) -static int pcl816_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl816_detach(struct comedi_device *dev); - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ #endif -static struct comedi_driver driver_pcl816 = { - .driver_name = "pcl816", - .module = THIS_MODULE, - .attach = pcl816_attach, - .detach = pcl816_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl816_board), -}; - -static int __init driver_pcl816_init_module(void) -{ - return comedi_driver_register(&driver_pcl816); -} - -static void __exit driver_pcl816_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl816); -} - -module_init(driver_pcl816_init_module); -module_exit(driver_pcl816_cleanup_module); - struct pcl816_private { unsigned int dma; /* used DMA, 0=don't use DMA */ @@ -1075,46 +1026,6 @@ static int set_rtc_irq_bit(unsigned char bit) } #endif -/* -============================================================================== - Free any resources that we have claimed -*/ -static void free_resources(struct comedi_device *dev) -{ - /* printk("free_resource()\n"); */ - if (dev->private) { - pcl816_ai_cancel(dev, devpriv->sub_ai); - pcl816_reset(dev); - if (devpriv->dma) - free_dma(devpriv->dma); - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); -#ifdef unused - if (devpriv->rtc_irq) - free_irq(devpriv->rtc_irq, dev); - if ((devpriv->dma_rtc) && (RTC_lock == 1)) { - if (devpriv->rtc_iobase) - release_region(devpriv->rtc_iobase, - devpriv->rtc_iosize); - } -#endif - } - - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->iobase) - release_region(dev->iobase, this_board->io_range); - /* printk("free_resource() end\n"); */ -} - -/* -============================================================================== - - Initialization - -*/ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -1340,21 +1251,69 @@ case COMEDI_SUBD_DO: return 0; } -/* -============================================================================== - Removes device - */ -static int pcl816_detach(struct comedi_device *dev) +static void pcl816_detach(struct comedi_device *dev) { - DEBUG(printk(KERN_INFO "comedi%d: pcl816: remove\n", dev->minor);) - free_resources(dev); + if (dev->private) { + pcl816_ai_cancel(dev, devpriv->sub_ai); + pcl816_reset(dev); + if (devpriv->dma) + free_dma(devpriv->dma); + if (devpriv->dmabuf[0]) + free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); + if (devpriv->dmabuf[1]) + free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); +#ifdef unused + if (devpriv->rtc_irq) + free_irq(devpriv->rtc_irq, dev); + if ((devpriv->dma_rtc) && (RTC_lock == 1)) { + if (devpriv->rtc_iobase) + release_region(devpriv->rtc_iobase, + devpriv->rtc_iosize); + } +#endif + } + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->iobase) + release_region(dev->iobase, this_board->io_range); #ifdef unused if (devpriv->dma_rtc) RTC_lock--; #endif - return 0; } +static const struct pcl816_board boardtypes[] = { + {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816, + &range_pcl816, PCLx1x_RANGE, + 0x00fc, /* IRQ mask */ + 0x0a, /* DMA mask */ + 0xffff, /* 16-bit card */ + 0xffff, /* D/A maxdata */ + 1024, + 1, /* ao chan list */ + 100}, + {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816, + &range_pcl816, PCLx1x_RANGE, + 0x00fc, + 0x0a, + 0x3fff, /* 14 bit card */ + 0x3fff, + 1024, + 1, + 100}, +}; + +static struct comedi_driver pcl816_driver = { + .driver_name = "pcl816", + .module = THIS_MODULE, + .attach = pcl816_attach, + .detach = pcl816_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl816_board), +}; +module_comedi_driver(pcl816_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 7344a53..1406c97 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -247,10 +247,6 @@ static const struct comedi_lrange range718_bipolar0_5 = static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} }; static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} }; -static int pcl818_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcl818_detach(struct comedi_device *dev); - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ @@ -277,56 +273,6 @@ struct pcl818_board { int is_818; }; -static const struct pcl818_board boardtypes[] = { - {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 1, 1}, - {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 1, 1}, - {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1}, - {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 0}, - /* pcm3718 */ - {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, - &range_unipolar5, PCLx1x_RANGE, 0x00fc, - 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board)) - -static struct comedi_driver driver_pcl818 = { - .driver_name = "pcl818", - .module = THIS_MODULE, - .attach = pcl818_attach, - .detach = pcl818_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcl818_board), -}; - -static int __init driver_pcl818_init_module(void) -{ - return comedi_driver_register(&driver_pcl818); -} - -static void __exit driver_pcl818_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcl818); -} - -module_init(driver_pcl818_init_module); -module_exit(driver_pcl818_cleanup_module); - struct pcl818_private { unsigned int dma; /* used DMA, 0=don't use DMA */ @@ -1688,48 +1634,6 @@ static int rtc_setfreq_irq(int freq) } #endif -/* -============================================================================== - Free any resources that we have claimed -*/ -static void free_resources(struct comedi_device *dev) -{ - /* printk("free_resource()\n"); */ - if (dev->private) { - pcl818_ai_cancel(dev, devpriv->sub_ai); - pcl818_reset(dev); - if (devpriv->dma) - free_dma(devpriv->dma); - if (devpriv->dmabuf[0]) - free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); - if (devpriv->dmabuf[1]) - free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); -#ifdef unused - if (devpriv->rtc_irq) - free_irq(devpriv->rtc_irq, dev); - if ((devpriv->dma_rtc) && (RTC_lock == 1)) { - if (devpriv->rtc_iobase) - release_region(devpriv->rtc_iobase, - devpriv->rtc_iosize); - } - if (devpriv->dma_rtc) - RTC_lock--; -#endif - } - - if (dev->irq) - free_irq(dev->irq, dev); - if (dev->iobase) - release_region(dev->iobase, devpriv->io_range); - /* printk("free_resource() end\n"); */ -} - -/* -============================================================================== - - Initialization - -*/ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { int ret; @@ -2020,17 +1924,71 @@ no_dma: return 0; } -/* -============================================================================== - Removes device - */ -static int pcl818_detach(struct comedi_device *dev) +static void pcl818_detach(struct comedi_device *dev) { - /* printk("comedi%d: pcl818: remove\n", dev->minor); */ - free_resources(dev); - return 0; + if (dev->private) { + pcl818_ai_cancel(dev, devpriv->sub_ai); + pcl818_reset(dev); + if (devpriv->dma) + free_dma(devpriv->dma); + if (devpriv->dmabuf[0]) + free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); + if (devpriv->dmabuf[1]) + free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]); +#ifdef unused + if (devpriv->rtc_irq) + free_irq(devpriv->rtc_irq, dev); + if ((devpriv->dma_rtc) && (RTC_lock == 1)) { + if (devpriv->rtc_iobase) + release_region(devpriv->rtc_iobase, + devpriv->rtc_iosize); + } + if (devpriv->dma_rtc) + RTC_lock--; +#endif + } + if (dev->irq) + free_irq(dev->irq, dev); + if (dev->iobase) + release_region(dev->iobase, devpriv->io_range); } +static const struct pcl818_board boardtypes[] = { + {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 1, 1}, + {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 1, 1}, + {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1}, + {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 0}, + /* pcm3718 */ + {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai, + &range_unipolar5, PCLx1x_RANGE, 0x00fc, + 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ }, +}; + +static struct comedi_driver pcl818_driver = { + .driver_name = "pcl818", + .module = THIS_MODULE, + .attach = pcl818_attach, + .detach = pcl818_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcl818_board), +}; +module_comedi_driver(pcl818_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index f5c0bd1..7492b8f 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -62,10 +62,6 @@ Copy/pasted/hacked from pcm724.c #define CR_A_MODE(a) ((a)<<5) #define CR_CW 0x80 -static int pcm3724_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcm3724_detach(struct comedi_device *dev); - struct pcm3724_board { const char *name; /* driver name */ int dio; /* num of DIO */ @@ -80,36 +76,8 @@ struct priv_pcm3724 { int dio_2; }; -static const struct pcm3724_board boardtypes[] = { - {"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,}, -}; - -#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcm3724_board)) #define this_board ((const struct pcm3724_board *)dev->board_ptr) -static struct comedi_driver driver_pcm3724 = { - .driver_name = "pcm3724", - .module = THIS_MODULE, - .attach = pcm3724_attach, - .detach = pcm3724_detach, - .board_name = &boardtypes[0].name, - .num_names = n_boardtypes, - .offset = sizeof(struct pcm3724_board), -}; - -static int __init driver_pcm3724_init_module(void) -{ - return comedi_driver_register(&driver_pcm3724); -} - -static void __exit driver_pcm3724_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3724); -} - -module_init(driver_pcm3724_init_module); -module_exit(driver_pcm3724_cleanup_module); - /* (setq c-basic-offset 8) */ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) @@ -305,7 +273,7 @@ static int pcm3724_attach(struct comedi_device *dev, return 0; } -static int pcm3724_detach(struct comedi_device *dev) +static void pcm3724_detach(struct comedi_device *dev) { int i; @@ -315,10 +283,23 @@ static int pcm3724_detach(struct comedi_device *dev) } if (dev->iobase) release_region(dev->iobase, this_board->io_range); - - return 0; } +static const struct pcm3724_board boardtypes[] = { + { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, }, +}; + +static struct comedi_driver pcm3724_driver = { + .driver_name = "pcm3724", + .module = THIS_MODULE, + .attach = pcm3724_attach, + .detach = pcm3724_detach, + .board_name = &boardtypes[0].name, + .num_names = ARRAY_SIZE(boardtypes), + .offset = sizeof(struct pcm3724_board), +}; +module_comedi_driver(pcm3724_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c index bada6b2..f8d1c64 100644 --- a/drivers/staging/comedi/drivers/pcm3730.c +++ b/drivers/staging/comedi/drivers/pcm3730.c @@ -28,29 +28,6 @@ Configuration options: #define PCM3730_DIB 2 #define PCM3730_DIC 3 -static int pcm3730_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcm3730_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcm3730 = { - .driver_name = "pcm3730", - .module = THIS_MODULE, - .attach = pcm3730_attach, - .detach = pcm3730_detach, -}; - -static int __init driver_pcm3730_init_module(void) -{ - return comedi_driver_register(&driver_pcm3730); -} - -static void __exit driver_pcm3730_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcm3730); -} - -module_init(driver_pcm3730_init_module); -module_exit(driver_pcm3730_cleanup_module); - static int pcm3730_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -156,16 +133,20 @@ static int pcm3730_attach(struct comedi_device *dev, return 0; } -static int pcm3730_detach(struct comedi_device *dev) +static void pcm3730_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pcm3730: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, PCM3730_SIZE); - - return 0; } +static struct comedi_driver pcm3730_driver = { + .driver_name = "pcm3730", + .module = THIS_MODULE, + .attach = pcm3730_attach, + .detach = pcm3730_detach, +}; +module_comedi_driver(pcm3730_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 23b3d77..1ec7d5c 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -57,19 +57,8 @@ struct pcmad_board_struct { const char *name; int n_ai_bits; }; -static const struct pcmad_board_struct pcmad_boards[] = { - { - .name = "pcmad12", - .n_ai_bits = 12, - }, - { - .name = "pcmad16", - .n_ai_bits = 16, - }, -}; #define this_board ((const struct pcmad_board_struct *)(dev->board_ptr)) -#define n_pcmad_boards ARRAY_SIZE(pcmad_boards) struct pcmad_priv_struct { int differential; @@ -77,31 +66,6 @@ struct pcmad_priv_struct { }; #define devpriv ((struct pcmad_priv_struct *)dev->private) -static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int pcmad_detach(struct comedi_device *dev); -static struct comedi_driver driver_pcmad = { - .driver_name = "pcmad", - .module = THIS_MODULE, - .attach = pcmad_attach, - .detach = pcmad_detach, - .board_name = &pcmad_boards[0].name, - .num_names = n_pcmad_boards, - .offset = sizeof(pcmad_boards[0]), -}; - -static int __init driver_pcmad_init_module(void) -{ - return comedi_driver_register(&driver_pcmad); -} - -static void __exit driver_pcmad_cleanup_module(void) -{ - comedi_driver_unregister(&driver_pcmad); -} - -module_init(driver_pcmad_init_module); -module_exit(driver_pcmad_cleanup_module); - #define TIMEOUT 100 static int pcmad_ai_insn_read(struct comedi_device *dev, @@ -175,19 +139,34 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int pcmad_detach(struct comedi_device *dev) +static void pcmad_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: pcmad: remove\n", dev->minor); - if (dev->irq) free_irq(dev->irq, dev); - if (dev->iobase) release_region(dev->iobase, PCMAD_SIZE); - - return 0; } +static const struct pcmad_board_struct pcmad_boards[] = { + { + .name = "pcmad12", + .n_ai_bits = 12, + }, { + .name = "pcmad16", + .n_ai_bits = 16, + }, +}; +static struct comedi_driver pcmad_driver = { + .driver_name = "pcmad", + .module = THIS_MODULE, + .attach = pcmad_attach, + .detach = pcmad_detach, + .board_name = &pcmad_boards[0].name, + .num_names = ARRAY_SIZE(pcmad_boards), + .offset = sizeof(pcmad_boards[0]), +}; +module_comedi_driver(pcmad_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 0e9ffa2..4786148 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -80,12 +80,6 @@ static const struct comedi_lrange pcmda12_ranges = { } }; -static const struct pcmda12_board pcmda12_boards[] = { - { - .name = "pcmda12", - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -99,137 +93,6 @@ struct pcmda12_private { #define devpriv ((struct pcmda12_private *)(dev->private)) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmda12_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmda12_detach(struct comedi_device *dev); - -static void zero_chans(struct comedi_device *dev); - -static struct comedi_driver driver = { - .driver_name = "pcmda12", - .module = THIS_MODULE, - .attach = pcmda12_attach, - .detach = pcmda12_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmda12_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmda12_boards[0].name, - .offset = sizeof(struct pcmda12_board), - .num_names = ARRAY_SIZE(pcmda12_boards), -}; - -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pcmda12_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - - iobase = it->options[0]; - printk(KERN_INFO - "comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name, - iobase, it->options[1] ? "simultaneous xfer mode enabled" : ""); - - if (!request_region(iobase, IOSIZE, driver.driver_name)) { - printk("I/O port conflict\n"); - return -EIO; - } - dev->iobase = iobase; - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) { - printk(KERN_ERR "cannot allocate private data structure\n"); - return -ENOMEM; - } - - devpriv->simultaneous_xfer_mode = it->options[1]; - - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the - * 96-channel version of the board. - */ - if (alloc_subdevices(dev, 1) < 0) { - printk(KERN_ERR "cannot allocate subdevice data structures\n"); - return -ENOMEM; - } - - s = dev->subdevices; - s->private = NULL; - s->maxdata = (0x1 << BITS) - 1; - s->range_table = &pcmda12_ranges; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = CHANS; - s->insn_write = &ao_winsn; - s->insn_read = &ao_rinsn; - - zero_chans(dev); /* clear out all the registers, basically */ - - printk(KERN_INFO "attached\n"); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcmda12_detach(struct comedi_device *dev) -{ - printk(KERN_INFO - "comedi%d: %s: remove\n", dev->minor, driver.driver_name); - if (dev->iobase) - release_region(dev->iobase, IOSIZE); - return 0; -} - static void zero_chans(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -301,22 +164,91 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } +static int pcmda12_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + unsigned long iobase; + + iobase = it->options[0]; + printk(KERN_INFO + "comedi%d: %s: io: %lx %s ", dev->minor, dev->driver->driver_name, + iobase, it->options[1] ? "simultaneous xfer mode enabled" : ""); + + if (!request_region(iobase, IOSIZE, dev->driver->driver_name)) { + printk("I/O port conflict\n"); + return -EIO; + } + dev->iobase = iobase; + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. */ -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); + dev->board_name = thisboard->name; + +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) { + printk(KERN_ERR "cannot allocate private data structure\n"); + return -ENOMEM; + } + + devpriv->simultaneous_xfer_mode = it->options[1]; + + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + * + * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the + * 96-channel version of the board. + */ + if (alloc_subdevices(dev, 1) < 0) { + printk(KERN_ERR "cannot allocate subdevice data structures\n"); + return -ENOMEM; + } + + s = dev->subdevices; + s->private = NULL; + s->maxdata = (0x1 << BITS) - 1; + s->range_table = &pcmda12_ranges; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = CHANS; + s->insn_write = &ao_winsn; + s->insn_read = &ao_rinsn; + + zero_chans(dev); /* clear out all the registers, basically */ + + printk(KERN_INFO "attached\n"); + + return 1; } -static void __exit driver_cleanup_module(void) +static void pcmda12_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver); + if (dev->iobase) + release_region(dev->iobase, IOSIZE); } -module_init(driver_init_module); -module_exit(driver_cleanup_module); +static const struct pcmda12_board pcmda12_boards[] = { + { + .name = "pcmda12", + }, +}; + +static struct comedi_driver pcmda12_driver = { + .driver_name = "pcmda12", + .module = THIS_MODULE, + .attach = pcmda12_attach, + .detach = pcmda12_detach, + .board_name = &pcmda12_boards[0].name, + .offset = sizeof(struct pcmda12_board), + .num_names = ARRAY_SIZE(pcmda12_boards), +}; +module_comedi_driver(pcmda12_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index eddac00..efed168 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -145,13 +145,6 @@ Configuration Options: #define PAGE_ENAB 2 #define PAGE_INT_ID 3 -static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); -static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); -static int ao_winsn(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - /* * Board descriptions for two imaginary boards. Describing the * boards in this way is optional, and completely driver-dependent. @@ -190,23 +183,6 @@ static const struct comedi_lrange ranges_ao = { RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)} }; -static const struct pcmmio_board pcmmio_boards[] = { - { - .name = "pcmmio", - .dio_num_asics = 1, - .dio_num_ports = 6, - .total_iosize = 32, - .ai_bits = 16, - .ao_bits = 16, - .n_ai_chans = 16, - .n_ao_chans = 8, - .ai_range_table = &ranges_ai, - .ao_range_table = &ranges_ao, - .ai_rinsn = ai_rinsn, - .ao_rinsn = ao_rinsn, - .ao_winsn = ao_winsn}, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -293,312 +269,6 @@ struct pcmmio_private { */ #define devpriv ((struct pcmmio_private *)dev->private) #define subpriv ((struct pcmmio_subdev_private *)s->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmmio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmmio_detach(struct comedi_device *dev); - -static struct comedi_driver driver = { - .driver_name = "pcmmio", - .module = THIS_MODULE, - .attach = pcmmio_attach, - .detach = pcmmio_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmmio_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmmio_boards[0].name, - .offset = sizeof(struct pcmmio_board), - .num_names = ARRAY_SIZE(pcmmio_boards), -}; - -static int pcmmio_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcmmio_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static irqreturn_t interrupt_pcmmio(int irq, void *d); -static void pcmmio_stop_intr(struct comedi_device *, struct comedi_subdevice *); -static int pcmmio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmmio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -/* some helper functions to deal with specifics of this device's registers */ -/* sets up/clears ASIC chips to defaults */ -static void init_asics(struct comedi_device *dev); -static void switch_page(struct comedi_device *dev, int asic, int page); -#ifdef notused -static void lock_port(struct comedi_device *dev, int asic, int port); -static void unlock_port(struct comedi_device *dev, int asic, int port); -#endif - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, - thisasic_chanct = 0; - unsigned long iobase; - unsigned int irq[MAX_ASICS]; - - iobase = it->options[0]; - irq[0] = it->options[1]; - - printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, - driver.driver_name, iobase); - - dev->iobase = iobase; - - if (!iobase || !request_region(iobase, - thisboard->total_iosize, - driver.driver_name)) { - printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); - return -EIO; - } - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", - dev->minor); - return -ENOMEM; - } - - for (asic = 0; asic < MAX_ASICS; ++asic) { - devpriv->asics[asic].num = asic; - devpriv->asics[asic].iobase = - dev->iobase + 16 + asic * ASIC_IOSIZE; - /* - * this gets actually set at the end of this function when we - * request_irqs - */ - devpriv->asics[asic].irq = 0; - spin_lock_init(&devpriv->asics[asic].spinlock); - } - - chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics; - n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); - n_subdevs = n_dio_subdevs + 2; - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", - dev->minor); - return -ENOMEM; - } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) - */ - if (alloc_subdevices(dev, n_subdevs) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", - dev->minor); - return -ENOMEM; - } - - /* First, AI */ - sdev_no = 0; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_range_table; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->type = COMEDI_SUBD_AI; - s->n_chan = thisboard->n_ai_chans; - s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ai_rinsn; - subpriv->iobase = dev->iobase + 0; - /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); - - /* Next, AO */ - ++sdev_no; - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_range_table; - s->subdev_flags = SDF_READABLE; - s->type = COMEDI_SUBD_AO; - s->n_chan = thisboard->n_ao_chans; - s->len_chanlist = s->n_chan; - s->insn_read = thisboard->ao_rinsn; - s->insn_write = thisboard->ao_winsn; - subpriv->iobase = dev->iobase + 8; - /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); - - ++sdev_no; - port = 0; - asic = 0; - for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmmio_dio_insn_bits; - s->insn_config = pcmmio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->dio.intr.asic = -1; - subpriv->dio.intr.first_chan = -1; - subpriv->dio.intr.asic_chan = -1; - subpriv->dio.intr.num_asic_chans = -1; - subpriv->dio.intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - subpriv->iobases[byte_no] = - devpriv->asics[asic].iobase + port; - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->dio.intr.asic < 0) { - /* - * this is an interrupt subdevice, - * so setup the struct - */ - subpriv->dio.intr.asic = asic; - subpriv->dio.intr.active = 0; - subpriv->dio.intr.stop_count = 0; - subpriv->dio.intr.first_chan = byte_no * 8; - subpriv->dio.intr.asic_chan = thisasic_chanct; - subpriv->dio.intr.num_asic_chans = - s->n_chan - subpriv->dio.intr.first_chan; - s->cancel = pcmmio_cancel; - s->do_cmd = pcmmio_cmd; - s->do_cmdtest = pcmmio_cmdtest; - s->len_chanlist = - subpriv->dio.intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->dio.intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - /* - * reset the asic to our first asic, - * to do intr subdevs - */ - asic = 0; - port = 0; - } - - } - - init_asics(dev); /* clear out all the registers, basically */ - - for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, thisboard->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; - } - devpriv->asics[asic].irq = irq[asic]; - } - - dev->irq = irq[0]; /* - * grr.. wish comedi dev struct supported - * multiple irqs.. - */ - - if (irq[0]) { - printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); - if (thisboard->dio_num_asics == 2 && irq[1]) - printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", - dev->minor, irq[1]); - } else { - printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor); - } - - printk(KERN_INFO "comedi%d: attached\n", dev->minor); - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcmmio_detach(struct comedi_device *dev) -{ - int i; - - printk(KERN_INFO "comedi%d: %s: remove\n", dev->minor, driver.driver_name); - if (dev->iobase) - release_region(dev->iobase, thisboard->total_iosize); - - for (i = 0; i < MAX_ASICS; ++i) { - if (devpriv && devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - - if (devpriv && devpriv->sprivs) - kfree(devpriv->sprivs); - - return 0; -} /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -667,7 +337,7 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, } #ifdef DAMMIT_ITS_BROKEN /* DEBUG */ - printk("data_out_byte %02x\n", (unsigned)byte); + printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte); #endif /* save the digital input lines for this byte.. */ s->state |= ((unsigned int)byte) << offset; @@ -751,6 +421,21 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void switch_page(struct comedi_device *dev, int asic, int page) +{ + if (asic < 0 || asic >= thisboard->dio_num_asics) + return; /* paranoia */ + if (page < 0 || page >= NUM_PAGES) + return; /* more paranoia */ + + devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; + devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; + + /* now write out the shadow register */ + outb(devpriv->asics[asic].pagelock, + devpriv->asics[asic].iobase + REG_PAGELOCK); +} + static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -788,21 +473,6 @@ static void init_asics(struct comedi_device *dev) } } -static void switch_page(struct comedi_device *dev, int asic, int page) -{ - if (asic < 0 || asic >= thisboard->dio_num_asics) - return; /* paranoia */ - if (page < 0 || page >= NUM_PAGES) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; - devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; - - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - devpriv->asics[asic].iobase + REG_PAGELOCK); -} - #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { @@ -831,6 +501,27 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) } #endif /* notused */ +static void pcmmio_stop_intr(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int nports, firstport, asic, port; + + asic = subpriv->dio.intr.asic; + if (asic < 0) + return; /* not an interrupt subdev */ + + subpriv->dio.intr.enabled_mask = 0; + subpriv->dio.intr.active = 0; + s->async->inttrig = 0; + nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; + firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; + switch_page(dev, asic, PAGE_ENAB); + for (port = firstport; port < firstport + nports; ++port) { + /* disable all intrs for this subdev.. */ + outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + } +} + static irqreturn_t interrupt_pcmmio(int irq, void *d) { int asic, got1 = 0; @@ -991,27 +682,6 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) return IRQ_HANDLED; } -static void pcmmio_stop_intr(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - int nports, firstport, asic, port; - - asic = subpriv->dio.intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->dio.intr.enabled_mask = 0; - subpriv->dio.intr.active = 0; - s->async->inttrig = 0; - nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - /* disable all intrs for this subdev.. */ - outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); - } -} - static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1340,22 +1010,261 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, return n; } +static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, + thisasic_chanct = 0; + unsigned long iobase; + unsigned int irq[MAX_ASICS]; + + iobase = it->options[0]; + irq[0] = it->options[1]; + + printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, + dev->driver->driver_name, iobase); + + dev->iobase = iobase; + + if (!iobase || !request_region(iobase, + thisboard->total_iosize, + dev->driver->driver_name)) { + printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); + return -EIO; + } + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. */ -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); + dev->board_name = thisboard->name; + +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { + printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", + dev->minor); + return -ENOMEM; + } + + for (asic = 0; asic < MAX_ASICS; ++asic) { + devpriv->asics[asic].num = asic; + devpriv->asics[asic].iobase = + dev->iobase + 16 + asic * ASIC_IOSIZE; + /* + * this gets actually set at the end of this function when we + * request_irqs + */ + devpriv->asics[asic].irq = 0; + spin_lock_init(&devpriv->asics[asic].spinlock); + } + + chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics; + n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); + n_subdevs = n_dio_subdevs + 2; + devpriv->sprivs = + kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), + GFP_KERNEL); + if (!devpriv->sprivs) { + printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", + dev->minor); + return -ENOMEM; + } + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + * + * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO) + */ + if (alloc_subdevices(dev, n_subdevs) < 0) { + printk(KERN_ERR "comedi%d: cannot allocate subdevice data structures\n", + dev->minor); + return -ENOMEM; + } + + /* First, AI */ + sdev_no = 0; + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = thisboard->ai_range_table; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->type = COMEDI_SUBD_AI; + s->n_chan = thisboard->n_ai_chans; + s->len_chanlist = s->n_chan; + s->insn_read = thisboard->ai_rinsn; + subpriv->iobase = dev->iobase + 0; + /* initialize the resource enable register by clearing it */ + outb(0, subpriv->iobase + 3); + outb(0, subpriv->iobase + 4 + 3); + + /* Next, AO */ + ++sdev_no; + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range_table; + s->subdev_flags = SDF_READABLE; + s->type = COMEDI_SUBD_AO; + s->n_chan = thisboard->n_ao_chans; + s->len_chanlist = s->n_chan; + s->insn_read = thisboard->ao_rinsn; + s->insn_write = thisboard->ao_winsn; + subpriv->iobase = dev->iobase + 8; + /* initialize the resource enable register by clearing it */ + outb(0, subpriv->iobase + 3); + outb(0, subpriv->iobase + 4 + 3); + + ++sdev_no; + port = 0; + asic = 0; + for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) { + int byte_no; + + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = 1; + s->range_table = &range_digital; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->type = COMEDI_SUBD_DIO; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; + s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); + subpriv->dio.intr.asic = -1; + subpriv->dio.intr.first_chan = -1; + subpriv->dio.intr.asic_chan = -1; + subpriv->dio.intr.num_asic_chans = -1; + subpriv->dio.intr.active = 0; + s->len_chanlist = 1; + + /* save the ioport address for each 'port' of 8 channels in the + subdevice */ + for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { + if (port >= PORTS_PER_ASIC) { + port = 0; + ++asic; + thisasic_chanct = 0; + } + subpriv->iobases[byte_no] = + devpriv->asics[asic].iobase + port; + + if (thisasic_chanct < + CHANS_PER_PORT * INTR_PORTS_PER_ASIC + && subpriv->dio.intr.asic < 0) { + /* + * this is an interrupt subdevice, + * so setup the struct + */ + subpriv->dio.intr.asic = asic; + subpriv->dio.intr.active = 0; + subpriv->dio.intr.stop_count = 0; + subpriv->dio.intr.first_chan = byte_no * 8; + subpriv->dio.intr.asic_chan = thisasic_chanct; + subpriv->dio.intr.num_asic_chans = + s->n_chan - subpriv->dio.intr.first_chan; + s->cancel = pcmmio_cancel; + s->do_cmd = pcmmio_cmd; + s->do_cmdtest = pcmmio_cmdtest; + s->len_chanlist = + subpriv->dio.intr.num_asic_chans; + } + thisasic_chanct += CHANS_PER_PORT; + } + spin_lock_init(&subpriv->dio.intr.spinlock); + + chans_left -= s->n_chan; + + if (!chans_left) { + /* + * reset the asic to our first asic, + * to do intr subdevs + */ + asic = 0; + port = 0; + } + + } + + init_asics(dev); /* clear out all the registers, basically */ + + for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { + if (irq[asic] + && request_irq(irq[asic], interrupt_pcmmio, + IRQF_SHARED, thisboard->name, dev)) { + int i; + /* unroll the allocated irqs.. */ + for (i = asic - 1; i >= 0; --i) { + free_irq(irq[i], dev); + devpriv->asics[i].irq = irq[i] = 0; + } + irq[asic] = 0; + } + devpriv->asics[asic].irq = irq[asic]; + } + + dev->irq = irq[0]; /* + * grr.. wish comedi dev struct supported + * multiple irqs.. + */ + + if (irq[0]) { + printk(KERN_DEBUG "comedi%d: irq: %u\n", dev->minor, irq[0]); + if (thisboard->dio_num_asics == 2 && irq[1]) + printk(KERN_DEBUG "comedi%d: second ASIC irq: %u\n", + dev->minor, irq[1]); + } else { + printk(KERN_INFO "comedi%d: (IRQ mode disabled)\n", dev->minor); + } + + printk(KERN_INFO "comedi%d: attached\n", dev->minor); + + return 1; } -static void __exit driver_cleanup_module(void) +static void pcmmio_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver); + int i; + + if (dev->iobase) + release_region(dev->iobase, thisboard->total_iosize); + for (i = 0; i < MAX_ASICS; ++i) { + if (devpriv && devpriv->asics[i].irq) + free_irq(devpriv->asics[i].irq, dev); + } + if (devpriv && devpriv->sprivs) + kfree(devpriv->sprivs); } -module_init(driver_init_module); -module_exit(driver_cleanup_module); +static const struct pcmmio_board pcmmio_boards[] = { + { + .name = "pcmmio", + .dio_num_asics = 1, + .dio_num_ports = 6, + .total_iosize = 32, + .ai_bits = 16, + .ao_bits = 16, + .n_ai_chans = 16, + .n_ao_chans = 8, + .ai_range_table = &ranges_ai, + .ao_range_table = &ranges_ao, + .ai_rinsn = ai_rinsn, + .ao_rinsn = ao_rinsn, + .ao_winsn = ao_winsn + }, +}; + +static struct comedi_driver pcmmio_driver = { + .driver_name = "pcmmio", + .module = THIS_MODULE, + .attach = pcmmio_attach, + .detach = pcmmio_detach, + .board_name = &pcmmio_boards[0].name, + .offset = sizeof(struct pcmmio_board), + .num_names = ARRAY_SIZE(pcmmio_boards), +}; +module_comedi_driver(pcmmio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 661ba2e..623381d5 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -155,19 +155,6 @@ struct pcmuio_board { const int num_ports; }; -static const struct pcmuio_board pcmuio_boards[] = { - { - .name = "pcmuio48", - .num_asics = 1, - .num_ports = 6, - }, - { - .name = "pcmuio96", - .num_asics = 2, - .num_ports = 12, - }, -}; - /* * Useful for shorthand access to the particular board structure */ @@ -218,262 +205,6 @@ struct pcmuio_private { */ #define devpriv ((struct pcmuio_private *)dev->private) #define subpriv ((struct pcmuio_subdev_private *)s->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int pcmuio_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int pcmuio_detach(struct comedi_device *dev); - -static struct comedi_driver driver = { - .driver_name = "pcmuio", - .module = THIS_MODULE, - .attach = pcmuio_attach, - .detach = pcmuio_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in pcmuio_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &pcmuio_boards[0].name, - .offset = sizeof(struct pcmuio_board), - .num_names = ARRAY_SIZE(pcmuio_boards), -}; - -static int pcmuio_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcmuio_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static irqreturn_t interrupt_pcmuio(int irq, void *d); -static void pcmuio_stop_intr(struct comedi_device *, struct comedi_subdevice *); -static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); - -/* some helper functions to deal with specifics of this device's registers */ -static void init_asics(struct comedi_device *dev); /* sets up/clears ASIC chips to defaults */ -static void switch_page(struct comedi_device *dev, int asic, int page); -#ifdef notused -static void lock_port(struct comedi_device *dev, int asic, int port); -static void unlock_port(struct comedi_device *dev, int asic, int port); -#endif - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; - unsigned long iobase; - unsigned int irq[MAX_ASICS]; - - iobase = it->options[0]; - irq[0] = it->options[1]; - irq[1] = it->options[2]; - - dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, - driver.driver_name, iobase); - - dev->iobase = iobase; - - if (!iobase || !request_region(iobase, - thisboard->num_asics * ASIC_IOSIZE, - driver.driver_name)) { - dev_err(dev->hw_dev, "I/O port conflict\n"); - return -EIO; - } - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { - dev_warn(dev->hw_dev, "cannot allocate private data structure\n"); - return -ENOMEM; - } - - for (asic = 0; asic < MAX_ASICS; ++asic) { - devpriv->asics[asic].num = asic; - devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE; - devpriv->asics[asic].irq = 0; /* this gets actually set at the end of - this function when we - request_irqs */ - spin_lock_init(&devpriv->asics[asic].spinlock); - } - - chans_left = CHANS_PER_ASIC * thisboard->num_asics; - n_subdevs = CALC_N_SUBDEVS(chans_left); - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); - return -ENOMEM; - } - /* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - * - * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the - * 96-channel version of the board. - */ - if (alloc_subdevices(dev, n_subdevs) < 0) { - dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); - return -ENOMEM; - } - - port = 0; - asic = 0; - for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = dev->subdevices + sdev_no; - s->private = devpriv->sprivs + sdev_no; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmuio_dio_insn_bits; - s->insn_config = pcmuio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->intr.asic = -1; - subpriv->intr.first_chan = -1; - subpriv->intr.asic_chan = -1; - subpriv->intr.num_asic_chans = -1; - subpriv->intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - subpriv->iobases[byte_no] = - devpriv->asics[asic].iobase + port; - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->intr.asic < 0) { - /* this is an interrupt subdevice, so setup the struct */ - subpriv->intr.asic = asic; - subpriv->intr.active = 0; - subpriv->intr.stop_count = 0; - subpriv->intr.first_chan = byte_no * 8; - subpriv->intr.asic_chan = thisasic_chanct; - subpriv->intr.num_asic_chans = - s->n_chan - subpriv->intr.first_chan; - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = pcmuio_cancel; - s->do_cmd = pcmuio_cmd; - s->do_cmdtest = pcmuio_cmdtest; - s->len_chanlist = subpriv->intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - asic = 0; /* reset the asic to our first asic, to do intr subdevs */ - port = 0; - } - - } - - init_asics(dev); /* clear out all the registers, basically */ - - for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], interrupt_pcmuio, - IRQF_SHARED, thisboard->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; - } - devpriv->asics[asic].irq = irq[asic]; - } - - dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple - irqs.. */ - - if (irq[0]) { - dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); - if (irq[1] && thisboard->num_asics == 2) - dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); - } else { - dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); - } - - - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int pcmuio_detach(struct comedi_device *dev) -{ - int i; - - dev_dbg(dev->hw_dev, "comedi%d: %s: remove\n", dev->minor, - driver.driver_name); - if (dev->iobase) - release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); - - for (i = 0; i < MAX_ASICS; ++i) { - if (devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - - if (devpriv && devpriv->sprivs) - kfree(devpriv->sprivs); - - return 0; -} /* DIO devices are slightly special. Although it is possible to * implement the insn_read/insn_write interface, it is much more @@ -621,6 +352,21 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, return insn->n; } +static void switch_page(struct comedi_device *dev, int asic, int page) +{ + if (asic < 0 || asic >= thisboard->num_asics) + return; /* paranoia */ + if (page < 0 || page >= NUM_PAGES) + return; /* more paranoia */ + + devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; + devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; + + /* now write out the shadow register */ + outb(devpriv->asics[asic].pagelock, + dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK); +} + static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -658,21 +404,6 @@ static void init_asics(struct comedi_device *dev) } } -static void switch_page(struct comedi_device *dev, int asic, int page) -{ - if (asic < 0 || asic >= thisboard->num_asics) - return; /* paranoia */ - if (page < 0 || page >= NUM_PAGES) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; - devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; - - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK); -} - #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { @@ -700,6 +431,27 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) } #endif /* notused */ +static void pcmuio_stop_intr(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int nports, firstport, asic, port; + + asic = subpriv->intr.asic; + if (asic < 0) + return; /* not an interrupt subdev */ + + subpriv->intr.enabled_mask = 0; + subpriv->intr.active = 0; + s->async->inttrig = 0; + nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT; + firstport = subpriv->intr.asic_chan / CHANS_PER_PORT; + switch_page(dev, asic, PAGE_ENAB); + for (port = firstport; port < firstport + nports; ++port) { + /* disable all intrs for this subdev.. */ + outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + } +} + static irqreturn_t interrupt_pcmuio(int irq, void *d) { int asic, got1 = 0; @@ -852,27 +604,6 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) return IRQ_HANDLED; } -static void pcmuio_stop_intr(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - int nports, firstport, asic, port; - - asic = subpriv->intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 0; - s->async->inttrig = 0; - nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->intr.asic_chan / CHANS_PER_PORT; - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - /* disable all intrs for this subdev.. */ - outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); - } -} - static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1014,22 +745,205 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, return comedi_pcm_cmdtest(dev, s, cmd); } +static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; + unsigned long iobase; + unsigned int irq[MAX_ASICS]; + + iobase = it->options[0]; + irq[0] = it->options[1]; + irq[1] = it->options[2]; + + dev_dbg(dev->hw_dev, "comedi%d: %s: io: %lx attached\n", dev->minor, + dev->driver->driver_name, iobase); + + dev->iobase = iobase; + + if (!iobase || !request_region(iobase, + thisboard->num_asics * ASIC_IOSIZE, + dev->driver->driver_name)) { + dev_err(dev->hw_dev, "I/O port conflict\n"); + return -EIO; + } + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. */ -static int __init driver_init_module(void) -{ - return comedi_driver_register(&driver); + dev->board_name = thisboard->name; + +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { + dev_warn(dev->hw_dev, "cannot allocate private data structure\n"); + return -ENOMEM; + } + + for (asic = 0; asic < MAX_ASICS; ++asic) { + devpriv->asics[asic].num = asic; + devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE; + devpriv->asics[asic].irq = 0; /* this gets actually set at the end of + this function when we + request_irqs */ + spin_lock_init(&devpriv->asics[asic].spinlock); + } + + chans_left = CHANS_PER_ASIC * thisboard->num_asics; + n_subdevs = CALC_N_SUBDEVS(chans_left); + devpriv->sprivs = + kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), + GFP_KERNEL); + if (!devpriv->sprivs) { + dev_warn(dev->hw_dev, "cannot allocate subdevice private data structures\n"); + return -ENOMEM; + } + /* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + * + * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the + * 96-channel version of the board. + */ + if (alloc_subdevices(dev, n_subdevs) < 0) { + dev_dbg(dev->hw_dev, "cannot allocate subdevice data structures\n"); + return -ENOMEM; + } + + port = 0; + asic = 0; + for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { + int byte_no; + + s = dev->subdevices + sdev_no; + s->private = devpriv->sprivs + sdev_no; + s->maxdata = 1; + s->range_table = &range_digital; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->type = COMEDI_SUBD_DIO; + s->insn_bits = pcmuio_dio_insn_bits; + s->insn_config = pcmuio_dio_insn_config; + s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); + subpriv->intr.asic = -1; + subpriv->intr.first_chan = -1; + subpriv->intr.asic_chan = -1; + subpriv->intr.num_asic_chans = -1; + subpriv->intr.active = 0; + s->len_chanlist = 1; + + /* save the ioport address for each 'port' of 8 channels in the + subdevice */ + for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { + if (port >= PORTS_PER_ASIC) { + port = 0; + ++asic; + thisasic_chanct = 0; + } + subpriv->iobases[byte_no] = + devpriv->asics[asic].iobase + port; + + if (thisasic_chanct < + CHANS_PER_PORT * INTR_PORTS_PER_ASIC + && subpriv->intr.asic < 0) { + /* this is an interrupt subdevice, so setup the struct */ + subpriv->intr.asic = asic; + subpriv->intr.active = 0; + subpriv->intr.stop_count = 0; + subpriv->intr.first_chan = byte_no * 8; + subpriv->intr.asic_chan = thisasic_chanct; + subpriv->intr.num_asic_chans = + s->n_chan - subpriv->intr.first_chan; + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = pcmuio_cancel; + s->do_cmd = pcmuio_cmd; + s->do_cmdtest = pcmuio_cmdtest; + s->len_chanlist = subpriv->intr.num_asic_chans; + } + thisasic_chanct += CHANS_PER_PORT; + } + spin_lock_init(&subpriv->intr.spinlock); + + chans_left -= s->n_chan; + + if (!chans_left) { + asic = 0; /* reset the asic to our first asic, to do intr subdevs */ + port = 0; + } + + } + + init_asics(dev); /* clear out all the registers, basically */ + + for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { + if (irq[asic] + && request_irq(irq[asic], interrupt_pcmuio, + IRQF_SHARED, thisboard->name, dev)) { + int i; + /* unroll the allocated irqs.. */ + for (i = asic - 1; i >= 0; --i) { + free_irq(irq[i], dev); + devpriv->asics[i].irq = irq[i] = 0; + } + irq[asic] = 0; + } + devpriv->asics[asic].irq = irq[asic]; + } + + dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple + irqs.. */ + + if (irq[0]) { + dev_dbg(dev->hw_dev, "irq: %u\n", irq[0]); + if (irq[1] && thisboard->num_asics == 2) + dev_dbg(dev->hw_dev, "second ASIC irq: %u\n", irq[1]); + } else { + dev_dbg(dev->hw_dev, "(IRQ mode disabled)\n"); + } + + + return 1; } -static void __exit driver_cleanup_module(void) +static void pcmuio_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver); + int i; + + if (dev->iobase) + release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics); + for (i = 0; i < MAX_ASICS; ++i) { + if (devpriv->asics[i].irq) + free_irq(devpriv->asics[i].irq, dev); + } + if (devpriv && devpriv->sprivs) + kfree(devpriv->sprivs); } -module_init(driver_init_module); -module_exit(driver_cleanup_module); +static const struct pcmuio_board pcmuio_boards[] = { + { + .name = "pcmuio48", + .num_asics = 1, + .num_ports = 6, + }, { + .name = "pcmuio96", + .num_asics = 2, + .num_ports = 12, + }, +}; + +static struct comedi_driver pcmuio_driver = { + .driver_name = "pcmuio", + .module = THIS_MODULE, + .attach = pcmuio_attach, + .detach = pcmuio_detach, + .board_name = &pcmuio_boards[0].name, + .offset = sizeof(struct pcmuio_board), + .num_names = ARRAY_SIZE(pcmuio_boards), +}; +module_comedi_driver(pcmuio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 831a576..e712048 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -41,20 +41,6 @@ Configuration options: #include <linux/ioport.h> -static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int poc_detach(struct comedi_device *dev); -static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcl733_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int pcl734_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - struct boarddef_struct { const char *name; unsigned int iosize; @@ -70,108 +56,9 @@ struct boarddef_struct { struct comedi_insn *, unsigned int *); const struct comedi_lrange *range; }; -static const struct boarddef_struct boards[] = { - { - .name = "dac02", - .iosize = 8, - /* .setup = dac02_setup, */ - .type = COMEDI_SUBD_AO, - .n_chan = 2, - .n_bits = 12, - .winsn = dac02_ao_winsn, - .rinsn = readback_insn, - .range = &range_unknown, - }, - { - .name = "pcl733", - .iosize = 4, - .type = COMEDI_SUBD_DI, - .n_chan = 32, - .n_bits = 1, - .insnbits = pcl733_insn_bits, - .range = &range_digital, - }, - { - .name = "pcl734", - .iosize = 4, - .type = COMEDI_SUBD_DO, - .n_chan = 32, - .n_bits = 1, - .insnbits = pcl734_insn_bits, - .range = &range_digital, - }, -}; -#define n_boards ARRAY_SIZE(boards) #define this_board ((const struct boarddef_struct *)dev->board_ptr) -static struct comedi_driver driver_poc = { - .driver_name = "poc", - .module = THIS_MODULE, - .attach = poc_attach, - .detach = poc_detach, - .board_name = &boards[0].name, - .num_names = n_boards, - .offset = sizeof(boards[0]), -}; - -static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - unsigned long iobase; - unsigned int iosize; - - iobase = it->options[0]; - printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, - this_board->name, iobase); - - dev->board_name = this_board->name; - - if (iobase == 0) { - printk(KERN_ERR "io base address required\n"); - return -EINVAL; - } - - iosize = this_board->iosize; - /* check if io addresses are available */ - if (!request_region(iobase, iosize, "dac02")) { - printk(KERN_ERR "I/O port conflict: failed to allocate ports " - "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1); - return -EIO; - } - dev->iobase = iobase; - - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0) - return -ENOMEM; - - /* analog output subdevice */ - s = dev->subdevices + 0; - s->type = this_board->type; - s->n_chan = this_board->n_chan; - s->maxdata = (1 << this_board->n_bits) - 1; - s->range_table = this_board->range; - s->insn_write = this_board->winsn; - s->insn_read = this_board->rinsn; - s->insn_bits = this_board->insnbits; - if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) - s->subdev_flags = SDF_WRITABLE; - - return 0; -} - -static int poc_detach(struct comedi_device *dev) -{ - /* only free stuff if it has been allocated by _attach */ - if (dev->iobase) - release_region(dev->iobase, this_board->iosize); - - printk(KERN_INFO "comedi%d: dac02: remove\n", dev->minor); - - return 0; -} - static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -248,18 +135,98 @@ static int pcl734_insn_bits(struct comedi_device *dev, return 2; } -static int __init driver_poc_init_module(void) +static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - return comedi_driver_register(&driver_poc); + struct comedi_subdevice *s; + unsigned long iobase; + unsigned int iosize; + + iobase = it->options[0]; + printk(KERN_INFO "comedi%d: poc: using %s iobase 0x%lx\n", dev->minor, + this_board->name, iobase); + + dev->board_name = this_board->name; + + if (iobase == 0) { + printk(KERN_ERR "io base address required\n"); + return -EINVAL; + } + + iosize = this_board->iosize; + /* check if io addresses are available */ + if (!request_region(iobase, iosize, "dac02")) { + printk(KERN_ERR "I/O port conflict: failed to allocate ports " + "0x%lx to 0x%lx\n", iobase, iobase + iosize - 1); + return -EIO; + } + dev->iobase = iobase; + + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0) + return -ENOMEM; + + /* analog output subdevice */ + s = dev->subdevices + 0; + s->type = this_board->type; + s->n_chan = this_board->n_chan; + s->maxdata = (1 << this_board->n_bits) - 1; + s->range_table = this_board->range; + s->insn_write = this_board->winsn; + s->insn_read = this_board->rinsn; + s->insn_bits = this_board->insnbits; + if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) + s->subdev_flags = SDF_WRITABLE; + + return 0; } -static void __exit driver_poc_cleanup_module(void) +static void poc_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver_poc); + if (dev->iobase) + release_region(dev->iobase, this_board->iosize); } -module_init(driver_poc_init_module); -module_exit(driver_poc_cleanup_module); +static const struct boarddef_struct boards[] = { + { + .name = "dac02", + .iosize = 8, + /* .setup = dac02_setup, */ + .type = COMEDI_SUBD_AO, + .n_chan = 2, + .n_bits = 12, + .winsn = dac02_ao_winsn, + .rinsn = readback_insn, + .range = &range_unknown, + }, { + .name = "pcl733", + .iosize = 4, + .type = COMEDI_SUBD_DI, + .n_chan = 32, + .n_bits = 1, + .insnbits = pcl733_insn_bits, + .range = &range_digital, + }, { + .name = "pcl734", + .iosize = 4, + .type = COMEDI_SUBD_DO, + .n_chan = 32, + .n_bits = 1, + .insnbits = pcl734_insn_bits, + .range = &range_digital, + }, +}; + +static struct comedi_driver poc_driver = { + .driver_name = "poc", + .module = THIS_MODULE, + .attach = poc_attach, + .detach = poc_detach, + .board_name = &boards[0].name, + .num_names = ARRAY_SIZE(boards), + .offset = sizeof(boards[0]), +}; +module_comedi_driver(poc_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index e0bb734..2f130b3 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -181,7 +181,7 @@ static const struct comedi_lrange range_daqp_ao = { 1, {BIP_RANGE(5)} }; /* comedi interface code */ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int daqp_detach(struct comedi_device *dev); +static void daqp_detach(struct comedi_device *dev); static struct comedi_driver driver_daqp = { .driver_name = "quatech_daqp_cs", .module = THIS_MODULE, @@ -922,15 +922,9 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 1; } -/* daqp_detach (called from comedi_comdig) does nothing. If the PCMCIA - * card is removed, daqp_cs_detach() is called by the pcmcia subsystem. - */ - -static int daqp_detach(struct comedi_device *dev) +static void daqp_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: detaching daqp\n", dev->minor); - - return 0; + /* Nothing to cleanup */ } /*==================================================================== @@ -1010,8 +1004,6 @@ static void daqp_cs_detach(struct pcmcia_device *link) { struct local_info_t *dev = link->priv; - dev_dbg(&link->dev, "daqp_cs_detach\n"); - dev->stop = 1; daqp_cs_release(link); @@ -1019,7 +1011,7 @@ static void daqp_cs_detach(struct pcmcia_device *link) dev_table[dev->table_index] = NULL; kfree(dev); -} /* daqp_cs_detach */ +} static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data) { diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 1384419..1678a0c 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -328,14 +328,6 @@ static const struct rtdBoard rtd520Boards[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) }, - { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, rtd520_pci_table); - /* * Useful for shorthand access to the particular board structure */ @@ -347,13 +339,13 @@ MODULE_DEVICE_TABLE(pci, rtd520_pci_table); */ struct rtdPrivate { /* memory mapped board structures */ - void *las0; - void *las1; - void *lcfg; + void __iomem *las0; + void __iomem *las1; + void __iomem *lcfg; unsigned long intCount; /* interrupt count */ long aiCount; /* total transfer size (samples) */ - int transCount; /* # to tranfer data. 0->1/2FIFO */ + int transCount; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ /* PCI device info */ @@ -377,8 +369,11 @@ struct rtdPrivate { u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */ u8 dioStatus; /* could be read back (dio0Ctrl) */ #ifdef USE_DMA - /* Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that size. - After transferring, interrupt processes 1/2 FIFO and passes to comedi */ + /* + * Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that + * size. After transferring, interrupt processes 1/2 FIFO and + * passes to comedi + */ s16 dma0Offset; /* current processing offset (0, 1/2) */ uint16_t *dma0Buff[DMA_CHAIN_COUNT]; /* DMA buffers (for ADC) */ dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT]; /* physical addresses */ @@ -581,7 +576,8 @@ struct rtdPrivate { /* User output N source select (write only) */ #define RtdUsrOutSource(dev, n, v) \ - writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT)) + writel(v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : \ + LAS0_UOUT1_SELECT)) /* Digital IO */ #define RtdDio0Read(dev) \ @@ -608,7 +604,8 @@ struct rtdPrivate { /* Write one data value (sign + 12bit + marker bits) */ /* Note: matches what DMA would put. Actual value << 3 */ #define RtdDacFifoPut(dev, n, v) \ - writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)) + writew((v), devpriv->las1 + (((n) == 0) ? LAS1_DAC1_FIFO : \ + LAS1_DAC2_FIFO)) /* Start single DAC conversion */ #define RtdDacUpdate(dev, n) \ @@ -625,7 +622,8 @@ struct rtdPrivate { /* Reset DAC FIFO */ #define RtdDacClearFifo(dev, n) \ - writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET)) + writel(0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : \ + LAS0_DAC2_RESET)) /* Set source for DMA 0 (write only, shadow?) */ #define RtdDma0Source(dev, n) \ @@ -705,22 +703,6 @@ struct rtdPrivate { #define RtdDma1Status(dev) \ readb(devpriv->lcfg+LCFG_DMACSR1) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attac/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int rtd_detach(struct comedi_device *dev); - -static struct comedi_driver rtd520Driver = { - .driver_name = DRV_NAME, - .module = THIS_MODULE, - .attach = rtd_attach, - .detach = rtd_detach, -}; - static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -737,7 +719,10 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -/* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */ +/* + * static int rtd_ai_poll(struct comedi_device *dev, + * struct comedi_subdevice *s); + */ static int rtd_ns_to_timer(unsigned int *ns, int roundMode); static irqreturn_t rtd_interrupt(int irq, void *d); static int rtd520_probe_fifo_depth(struct comedi_device *dev); @@ -857,7 +842,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) DPRINTK("rtd520: PCI latency = %d\n", pci_latency); } - /* Undocumented EPLD version (doesn't match RTD driver results) */ + /* + * Undocumented EPLD version (doesn't match RTD driver results) + */ /*DPRINTK ("rtd520: Reading epld from %p\n", devpriv->las0+0); epld_version = readl (devpriv->las0+0); @@ -970,9 +957,11 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) #ifdef USE_DMA if (dev->irq > 0) { printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); - /* The PLX9080 has 2 DMA controllers, but there could be 4 sources: - ADC, digital, DAC1, and DAC2. Since only the ADC supports cmd mode - right now, this isn't an issue (yet) */ + /* + * The PLX9080 has 2 DMA controllers, but there could be + * 4 sources: ADC, digital, DAC1, and DAC2. Since only the + * ADC supports cmd mode right now, this isn't an issue (yet) + */ devpriv->dma0Offset = 0; for (index = 0; index < DMA_CHAIN_COUNT; index++) { @@ -988,10 +977,14 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", index, - devpriv->dma0Buff[index], devpriv->dma0BuffPhysAddr[index]); */ + devpriv->dma0Buff[index], + devpriv->dma0BuffPhysAddr[index]); */ } - /* setup DMA descriptor ring (use cpu_to_le32 for byte ordering?) */ + /* + * setup DMA descriptor ring (use cpu_to_le32 for byte + * ordering?) + */ devpriv->dma0Chain = pci_alloc_consistent(devpriv->pci_dev, sizeof(struct plx_dma_desc) * @@ -1088,30 +1081,12 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif } -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int rtd_detach(struct comedi_device *dev) +static void rtd_detach(struct comedi_device *dev) { #ifdef USE_DMA int index; #endif - DPRINTK("comedi%d: rtd520: removing (%ld ints)\n", - dev->minor, (devpriv ? devpriv->intCount : 0L)); - if (devpriv && devpriv->lcfg) { - DPRINTK - ("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n", - 0xffff & RtdInterruptStatus(dev), - 0xffff & RtdInterruptOverrunStatus(dev), - (0xffff & RtdFifoStatus(dev)) ^ 0x6666); - } - if (devpriv) { /* Shut down any board ops by resetting it */ #ifdef USE_DMA @@ -1148,37 +1123,24 @@ static int rtd_detach(struct comedi_device *dev) devpriv->dma0Chain = NULL; } #endif /* USE_DMA */ - - /* release IRQ */ if (dev->irq) { - /* disable interrupt controller */ RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev) & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E)); free_irq(dev->irq, dev); } - - /* release all regions that were allocated */ if (devpriv->las0) iounmap(devpriv->las0); - if (devpriv->las1) iounmap(devpriv->las1); - if (devpriv->lcfg) iounmap(devpriv->lcfg); - if (devpriv->pci_dev) { if (devpriv->got_regions) comedi_pci_disable(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); } } - - printk(KERN_INFO "comedi%d: rtd520: removed.\n", dev->minor); - - return 0; } /* @@ -1278,7 +1240,8 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) } } if (i == limit) { - printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME); + printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", + DRV_NAME); return -EIO; } RtdAdcClearFifo(dev); @@ -1378,9 +1341,10 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = RtdAdcFifoGet(dev); /* get 2s comp value */ d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) - sample = d + 2048; /* convert to comedi unsigned data */ - else + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else sample = d; if (!comedi_buf_put(s->async, sample)) @@ -1406,9 +1370,10 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) } d = d >> 3; /* low 3 bits are marker lines */ - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) - sample = d + 2048; /* convert to comedi unsigned data */ - else + if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { + /* convert to comedi unsigned data */ + sample = d + 2048; + } else sample = d; if (!comedi_buf_put(s->async, sample)) @@ -1525,7 +1490,9 @@ static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) comedi_buf_memcpy_to(s->async, 0, dp, n); comedi_buf_write_free(s->async, n); - /* always at least 1 scan -- 1/2 FIFO is larger than our max scan list */ + /* + * always at least 1 scan -- 1/2 FIFO is larger than our max scan list + */ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ @@ -1989,7 +1956,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) (TRANS_TARGET_PERIOD * cmd->chanlist_len) / cmd->scan_begin_arg; if (devpriv->transCount < cmd->chanlist_len) { - /* tranfer after each scan (and avoid 0) */ + /* transfer after each scan (and avoid 0) */ devpriv->transCount = cmd->chanlist_len; } else { /* make a multiple of scan length */ devpriv->transCount = @@ -2005,12 +1972,12 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->transCount = 0; devpriv->flags &= ~SEND_EOS; } else { - /* interrupt for each tranfer */ + /* interrupt for each transfer */ RtdAboutCounter(dev, devpriv->transCount - 1); } DPRINTK - ("rtd520: scanLen=%d tranferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", + ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, cmd->scan_begin_arg, devpriv->flags); } else { /* unknown timing, just use 1/2 FIFO */ @@ -2348,47 +2315,38 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __devinit rtd520Driver_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) +static struct comedi_driver rtd520_driver = { + .driver_name = "rtd520", + .module = THIS_MODULE, + .attach = rtd_attach, + .detach = rtd_detach, +}; + +static int __devinit rtd520_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, rtd520Driver.driver_name); + return comedi_pci_auto_config(dev, &rtd520_driver); } -static void __devexit rtd520Driver_pci_remove(struct pci_dev *dev) +static void __devexit rtd520_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver rtd520Driver_pci_driver = { - .id_table = rtd520_pci_table, - .probe = &rtd520Driver_pci_probe, - .remove = __devexit_p(&rtd520Driver_pci_remove) +static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x7520) }, + { PCI_DEVICE(PCI_VENDOR_ID_RTD, 0x4520) }, + { 0 } }; +MODULE_DEVICE_TABLE(pci, rtd520_pci_table); -static int __init rtd520Driver_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&rtd520Driver); - if (retval < 0) - return retval; - - rtd520Driver_pci_driver.name = (char *)rtd520Driver.driver_name; - return pci_register_driver(&rtd520Driver_pci_driver); -} - -static void __exit rtd520Driver_cleanup_module(void) -{ - pci_unregister_driver(&rtd520Driver_pci_driver); - comedi_driver_unregister(&rtd520Driver); -} - -module_init(rtd520Driver_init_module); -module_exit(rtd520Driver_cleanup_module); +static struct pci_driver rtd520_pci_driver = { + .name = "rtd520", + .id_table = rtd520_pci_table, + .probe = rtd520_pci_probe, + .remove = __devexit_p(rtd520_pci_remove), +}; +module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 72042b8..f0eb52a 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -138,39 +138,8 @@ struct rti800_board { int has_ao; }; -static const struct rti800_board boardtypes[] = { - {"rti800", 0}, - {"rti815", 1}, -}; - #define this_board ((const struct rti800_board *)dev->board_ptr) -static int rti800_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int rti800_detach(struct comedi_device *dev); -static struct comedi_driver driver_rti800 = { - .driver_name = "rti800", - .module = THIS_MODULE, - .attach = rti800_attach, - .detach = rti800_detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].name, - .offset = sizeof(struct rti800_board), -}; - -static int __init driver_rti800_init_module(void) -{ - return comedi_driver_register(&driver_rti800); -} - -static void __exit driver_rti800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti800); -} - -module_init(driver_rti800_init_module); -module_exit(driver_rti800_cleanup_module); - static irqreturn_t rti800_interrupt(int irq, void *dev); struct rti800_private { @@ -474,19 +443,30 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int rti800_detach(struct comedi_device *dev) +static void rti800_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: rti800: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, RTI800_SIZE); - if (dev->irq) free_irq(dev->irq, dev); - - return 0; } +static const struct rti800_board boardtypes[] = { + { "rti800", 0 }, + { "rti815", 1 }, +}; + +static struct comedi_driver rti800_driver = { + .driver_name = "rti800", + .module = THIS_MODULE, + .attach = rti800_attach, + .detach = rti800_detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].name, + .offset = sizeof(struct rti800_board), +}; +module_comedi_driver(rti800_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index f59cb11..09da5c2 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -47,29 +47,6 @@ Configuration Options: #define RTI802_DATALOW 1 #define RTI802_DATAHIGH 2 -static int rti802_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int rti802_detach(struct comedi_device *dev); -static struct comedi_driver driver_rti802 = { - .driver_name = "rti802", - .module = THIS_MODULE, - .attach = rti802_attach, - .detach = rti802_detach, -}; - -static int __init driver_rti802_init_module(void) -{ - return comedi_driver_register(&driver_rti802); -} - -static void __exit driver_rti802_cleanup_module(void) -{ - comedi_driver_unregister(&driver_rti802); -} - -module_init(driver_rti802_init_module); -module_exit(driver_rti802_cleanup_module); - struct rti802_private { enum { dac_2comp, dac_straight @@ -152,16 +129,20 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } -static int rti802_detach(struct comedi_device *dev) +static void rti802_detach(struct comedi_device *dev) { - printk(KERN_INFO "comedi%d: rti802: remove\n", dev->minor); - if (dev->iobase) release_region(dev->iobase, RTI802_SIZE); - - return 0; } +static struct comedi_driver rti802_driver = { + .driver_name = "rti802", + .module = THIS_MODULE, + .attach = rti802_attach, + .detach = rti802_detach, +}; +module_comedi_driver(rti802_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 2b34dae..7a56434 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -230,287 +230,6 @@ struct s526_private { */ #define devpriv ((struct s526_private *)dev->private) -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int s526_detach(struct comedi_device *dev); -static struct comedi_driver driver_s526 = { - .driver_name = "s526", - .module = THIS_MODULE, - .attach = s526_attach, - .detach = s526_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in s526_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &s526_boards[0].name, - .offset = sizeof(struct s526_board), - .num_names = ARRAY_SIZE(s526_boards), -}; - -static int s526_gpct_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int s526_gpct_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_gpct_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int s526_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int s526_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int iobase; - int i, n; -/* short value; */ -/* int subdev_channel = 0; */ - union cmReg cmReg; - - printk(KERN_INFO "comedi%d: s526: ", dev->minor); - - iobase = it->options[0]; - if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) { - comedi_error(dev, "I/O port conflict"); - return -EIO; - } - dev->iobase = iobase; - - printk("iobase=0x%lx\n", dev->iobase); - - /*** make it a little quieter, exw, 8/29/06 - for (i = 0; i < S526_NUM_PORTS; i++) { - printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), - inw(ADDR_REG(s526_ports[i]))); - } - ***/ - -/* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. - */ - dev->board_ptr = &s526_boards[0]; - - dev->board_name = thisboard->name; - -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct s526_private)) < 0) - return -ENOMEM; - -/* - * Allocate the subdevice structures. alloc_subdevice() is a - * convenient macro defined in comedidev.h. - */ - dev->n_subdevices = 4; - if (alloc_subdevices(dev, dev->n_subdevices) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; - /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */ - s->n_chan = thisboard->gpct_chans; - s->maxdata = 0x00ffffff; /* 24 bit counter */ - s->insn_read = s526_gpct_rinsn; - s->insn_config = s526_gpct_insn_config; - s->insn_write = s526_gpct_winsn; - - /* Command are not implemented yet, however they are necessary to - allocate the necessary memory for the comedi_async struct (used - to trigger the GPCT in case of pulsegenerator function */ - /* s->do_cmd = s526_gpct_cmd; */ - /* s->do_cmdtest = s526_gpct_cmdtest; */ - /* s->cancel = s526_gpct_cancel; */ - - s = dev->subdevices + 1; - /* dev->read_subdev=s; */ - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - /* we support differential */ - s->subdev_flags = SDF_READABLE | SDF_DIFF; - /* channels 0 to 7 are the regular differential inputs */ - /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */ - s->n_chan = 10; - s->maxdata = 0xffff; - s->range_table = &range_bipolar10; - s->len_chanlist = 16; /* This is the maximum chanlist length that - the board can handle */ - s->insn_read = s526_ai_rinsn; - s->insn_config = s526_ai_insn_config; - - s = dev->subdevices + 2; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 4; - s->maxdata = 0xffff; - s->range_table = &range_bipolar10; - s->insn_write = s526_ao_winsn; - s->insn_read = s526_ao_rinsn; - - s = dev->subdevices + 3; - /* digital i/o subdevice */ - if (thisboard->have_dio) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = s526_dio_insn_bits; - s->insn_config = s526_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - printk(KERN_INFO "attached\n"); - - return 1; - -#if 0 - /* Example of Counter Application */ - /* One-shot (software trigger) */ - cmReg.reg.coutSource = 0; /* out RCAP */ - cmReg.reg.coutPolarity = 1; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 1;/* Auto load 0:disabled, 1:enabled */ - cmReg.reg.hwCtEnableSource = 3; /* NOT RCAP */ - cmReg.reg.ctEnableCtrl = 2; /* Hardware */ - cmReg.reg.clockSource = 2; /* Internal */ - cmReg.reg.countDir = 1; /* Down */ - cmReg.reg.countDirCtrl = 1; /* Software */ - cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ - cmReg.reg.preloadRegSel = 0; /* PR0 */ - cmReg.reg.reserved = 0; - - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); - - outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); - outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); - - /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); - /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); - /* Reset RCAP (fires one-shot) */ - outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); - -#else - - /* Set Counter Mode Register */ - cmReg.reg.coutSource = 0; /* out RCAP */ - cmReg.reg.coutPolarity = 0; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */ - cmReg.reg.hwCtEnableSource = 2; /* NOT RCAP */ - cmReg.reg.ctEnableCtrl = 1; /* 1: Software, >1 : Hardware */ - cmReg.reg.clockSource = 3; /* x4 */ - cmReg.reg.countDir = 0; /* up */ - cmReg.reg.countDirCtrl = 0; /* quadrature */ - cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ - cmReg.reg.preloadRegSel = 0; /* PR0 */ - cmReg.reg.reserved = 0; - - n = 0; - printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n", - cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); - udelay(1000); - printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(ADDR_CHAN_REG(REG_C0M, n))); - - /* Load the pre-load register high word */ -/* value = (short) (0x55); */ -/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */ - - /* Load the pre-load register low word */ -/* value = (short)(0xaa55); */ -/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */ - - /* Write the Counter Control Register */ -/* outw(value, ADDR_CHAN_REG(REG_C0C, 0)); */ - - /* Reset the counter if it is software preload */ - if (cmReg.reg.autoLoadResetRcap == 0) { - /* Reset the counter */ - outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); - /* Load the counter from PR0 */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); - } - - outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); - udelay(1000); - printk(KERN_INFO "Read back mode reg=0x%04x\n", - inw(ADDR_CHAN_REG(REG_C0M, n))); - -#endif - printk(KERN_INFO "Current registres:\n"); - - for (i = 0; i < S526_NUM_PORTS; i++) { - printk(KERN_INFO "0x%02lx: 0x%04x\n", - ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i]))); - } - return 1; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static int s526_detach(struct comedi_device *dev) -{ - printk(KERN_INFO "comedi%d: s526: remove\n", dev->minor); - - if (dev->iobase > 0) - release_region(dev->iobase, S526_IOSIZE); - - return 0; -} - static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1023,22 +742,218 @@ static int s526_dio_insn_config(struct comedi_device *dev, return 1; } +static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + int iobase; + int i, n; +/* short value; */ +/* int subdev_channel = 0; */ + union cmReg cmReg; + + printk(KERN_INFO "comedi%d: s526: ", dev->minor); + + iobase = it->options[0]; + if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) { + comedi_error(dev, "I/O port conflict"); + return -EIO; + } + dev->iobase = iobase; + + printk("iobase=0x%lx\n", dev->iobase); + + /*** make it a little quieter, exw, 8/29/06 + for (i = 0; i < S526_NUM_PORTS; i++) { + printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), + inw(ADDR_REG(s526_ports[i]))); + } + ***/ + /* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. + * Initialize dev->board_name. Note that we can use the "thisboard" + * macro now, since we just initialized it in the last line. */ -static int __init driver_s526_init_module(void) -{ - return comedi_driver_register(&driver_s526); + dev->board_ptr = &s526_boards[0]; + + dev->board_name = thisboard->name; + +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if (alloc_private(dev, sizeof(struct s526_private)) < 0) + return -ENOMEM; + +/* + * Allocate the subdevice structures. alloc_subdevice() is a + * convenient macro defined in comedidev.h. + */ + dev->n_subdevices = 4; + if (alloc_subdevices(dev, dev->n_subdevices) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; + /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */ + s->n_chan = thisboard->gpct_chans; + s->maxdata = 0x00ffffff; /* 24 bit counter */ + s->insn_read = s526_gpct_rinsn; + s->insn_config = s526_gpct_insn_config; + s->insn_write = s526_gpct_winsn; + + /* Command are not implemented yet, however they are necessary to + allocate the necessary memory for the comedi_async struct (used + to trigger the GPCT in case of pulsegenerator function */ + /* s->do_cmd = s526_gpct_cmd; */ + /* s->do_cmdtest = s526_gpct_cmdtest; */ + /* s->cancel = s526_gpct_cancel; */ + + s = dev->subdevices + 1; + /* dev->read_subdev=s; */ + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + /* we support differential */ + s->subdev_flags = SDF_READABLE | SDF_DIFF; + /* channels 0 to 7 are the regular differential inputs */ + /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */ + s->n_chan = 10; + s->maxdata = 0xffff; + s->range_table = &range_bipolar10; + s->len_chanlist = 16; /* This is the maximum chanlist length that + the board can handle */ + s->insn_read = s526_ai_rinsn; + s->insn_config = s526_ai_insn_config; + + s = dev->subdevices + 2; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 4; + s->maxdata = 0xffff; + s->range_table = &range_bipolar10; + s->insn_write = s526_ao_winsn; + s->insn_read = s526_ao_rinsn; + + s = dev->subdevices + 3; + /* digital i/o subdevice */ + if (thisboard->have_dio) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = s526_dio_insn_bits; + s->insn_config = s526_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + printk(KERN_INFO "attached\n"); + + return 1; + +#if 0 + /* Example of Counter Application */ + /* One-shot (software trigger) */ + cmReg.reg.coutSource = 0; /* out RCAP */ + cmReg.reg.coutPolarity = 1; /* Polarity inverted */ + cmReg.reg.autoLoadResetRcap = 1;/* Auto load 0:disabled, 1:enabled */ + cmReg.reg.hwCtEnableSource = 3; /* NOT RCAP */ + cmReg.reg.ctEnableCtrl = 2; /* Hardware */ + cmReg.reg.clockSource = 2; /* Internal */ + cmReg.reg.countDir = 1; /* Down */ + cmReg.reg.countDirCtrl = 1; /* Software */ + cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ + cmReg.reg.preloadRegSel = 0; /* PR0 */ + cmReg.reg.reserved = 0; + + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); + + outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); + outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); + + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Reset RCAP (fires one-shot) */ + outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + +#else + + /* Set Counter Mode Register */ + cmReg.reg.coutSource = 0; /* out RCAP */ + cmReg.reg.coutPolarity = 0; /* Polarity inverted */ + cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */ + cmReg.reg.hwCtEnableSource = 2; /* NOT RCAP */ + cmReg.reg.ctEnableCtrl = 1; /* 1: Software, >1 : Hardware */ + cmReg.reg.clockSource = 3; /* x4 */ + cmReg.reg.countDir = 0; /* up */ + cmReg.reg.countDirCtrl = 0; /* quadrature */ + cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ + cmReg.reg.preloadRegSel = 0; /* PR0 */ + cmReg.reg.reserved = 0; + + n = 0; + printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n", + cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); + udelay(1000); + printk(KERN_INFO "Read back mode reg=0x%04x\n", + inw(ADDR_CHAN_REG(REG_C0M, n))); + + /* Load the pre-load register high word */ +/* value = (short) (0x55); */ +/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */ + + /* Load the pre-load register low word */ +/* value = (short)(0xaa55); */ +/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */ + + /* Write the Counter Control Register */ +/* outw(value, ADDR_CHAN_REG(REG_C0C, 0)); */ + + /* Reset the counter if it is software preload */ + if (cmReg.reg.autoLoadResetRcap == 0) { + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); + } + + outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); + udelay(1000); + printk(KERN_INFO "Read back mode reg=0x%04x\n", + inw(ADDR_CHAN_REG(REG_C0M, n))); + +#endif + printk(KERN_INFO "Current registres:\n"); + + for (i = 0; i < S526_NUM_PORTS; i++) { + printk(KERN_INFO "0x%02lx: 0x%04x\n", + ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i]))); + } + return 1; } -static void __exit driver_s526_cleanup_module(void) +static void s526_detach(struct comedi_device *dev) { - comedi_driver_unregister(&driver_s526); + if (dev->iobase > 0) + release_region(dev->iobase, S526_IOSIZE); } -module_init(driver_s526_init_module); -module_exit(driver_s526_cleanup_module); +static struct comedi_driver s526_driver = { + .driver_name = "s526", + .module = THIS_MODULE, + .attach = s526_attach, + .detach = s526_detach, + .board_name = &s526_boards[0].name, + .offset = sizeof(struct s526_board), + .num_names = ARRAY_SIZE(s526_boards), +}; +module_comedi_driver(s526_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 23fc64b..7beb8f6 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -79,12 +79,17 @@ INSN_CONFIG instructions: #include "comedi_fc.h" #include "s626.h" -MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>"); -MODULE_DESCRIPTION("Sensoray 626 Comedi driver module"); -MODULE_LICENSE("GPL"); +#define PCI_VENDOR_ID_S626 0x1131 +#define PCI_DEVICE_ID_S626 0x7146 +#define PCI_SUBVENDOR_ID_S626 0x6000 +#define PCI_SUBDEVICE_ID_S626 0x0272 struct s626_board { const char *name; + int vendor_id; + int device_id; + int subvendor_id; + int subdevice_id; int ai_chans; int ai_bits; int ao_chans; @@ -97,6 +102,10 @@ struct s626_board { static const struct s626_board s626_boards[] = { { .name = "s626", + .vendor_id = PCI_VENDOR_ID_S626, + .device_id = PCI_DEVICE_ID_S626, + .subvendor_id = PCI_SUBVENDOR_ID_S626, + .subdevice_id = PCI_SUBDEVICE_ID_S626, .ai_chans = S626_ADC_CHANNELS, .ai_bits = 14, .ao_chans = S626_DAC_CHANNELS, @@ -108,30 +117,6 @@ static const struct s626_board s626_boards[] = { }; #define thisboard ((const struct s626_board *)dev->board_ptr) -#define PCI_VENDOR_ID_S626 0x1131 -#define PCI_DEVICE_ID_S626 0x7146 - -/* - * For devices with vendor:device id == 0x1131:0x7146 you must specify - * also subvendor:subdevice ids, because otherwise it will conflict with - * Philips SAA7146 media/dvb based cards. - */ -static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { - {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, s626_pci_table); - -static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int s626_detach(struct comedi_device *dev); - -static struct comedi_driver driver_s626 = { - .driver_name = "s626", - .module = THIS_MODULE, - .attach = s626_attach, - .detach = s626_detach, -}; struct s626_private { struct pci_dev *pdev; @@ -224,44 +209,6 @@ static struct dio_private *dio_private_word[]={ #define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) -static int __devinit driver_s626_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, driver_s626.driver_name); -} - -static void __devexit driver_s626_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_s626_pci_driver = { - .id_table = s626_pci_table, - .probe = &driver_s626_pci_probe, - .remove = __devexit_p(&driver_s626_pci_remove) -}; - -static int __init driver_s626_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_s626); - if (retval < 0) - return retval; - - driver_s626_pci_driver.name = (char *)driver_s626.driver_name; - return pci_register_driver(&driver_s626_pci_driver); -} - -static void __exit driver_s626_cleanup_module(void) -{ - pci_unregister_driver(&driver_s626_pci_driver); - comedi_driver_unregister(&driver_s626); -} - -module_init(driver_s626_init_module); -module_exit(driver_s626_cleanup_module); - /* ioctl routines */ static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, @@ -554,17 +501,17 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) resource_size_t resourceStart; dma_addr_t appdma; struct comedi_subdevice *s; - const struct pci_device_id *ids; struct pci_dev *pdev = NULL; if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) { - ids = &s626_pci_table[i]; + for (i = 0; i < ARRAY_SIZE(s626_boards) && !pdev; i++) { do { - pdev = pci_get_subsys(ids->vendor, ids->device, - ids->subvendor, ids->subdevice, + pdev = pci_get_subsys(s626_boards[i].vendor_id, + s626_boards[i].device_id, + s626_boards[i].subvendor_id, + s626_boards[i].subdevice_id, pdev); if ((it->options[0] || it->options[1]) && pdev) { @@ -1365,7 +1312,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) return IRQ_HANDLED; } -static int s626_detach(struct comedi_device *dev) +static void s626_detach(struct comedi_device *dev) { if (devpriv) { /* stop ai_command */ @@ -1389,20 +1336,14 @@ static int s626_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); - if (devpriv->base_addr) iounmap(devpriv->base_addr); - if (devpriv->pdev) { if (devpriv->got_regions) comedi_pci_disable(devpriv->pdev); pci_dev_put(devpriv->pdev); } } - - DEBUG("s626_detach: S626 detached!\n"); - - return 0; } /* @@ -3367,3 +3308,45 @@ static void CountersInit(struct comedi_device *dev) DEBUG("CountersInit: counters initialized\n"); } + +static struct comedi_driver s626_driver = { + .driver_name = "s626", + .module = THIS_MODULE, + .attach = s626_attach, + .detach = s626_detach, +}; + +static int __devinit s626_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &s626_driver); +} + +static void __devexit s626_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +/* + * For devices with vendor:device id == 0x1131:0x7146 you must specify + * also subvendor:subdevice ids, because otherwise it will conflict with + * Philips SAA7146 media/dvb based cards. + */ +static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { + { PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, + PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, s626_pci_table); + +static struct pci_driver s626_pci_driver = { + .name = "s626", + .id_table = s626_pci_table, + .probe = s626_pci_probe, + .remove = __devexit_p(s626_pci_remove), +}; +module_comedi_pci_driver(s626_driver, s626_pci_driver); + +MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>"); +MODULE_DESCRIPTION("Sensoray 626 Comedi driver module"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index d880c2f..6342bc5 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -43,20 +43,10 @@ Status: in development #include <linux/serial.h> #include <linux/poll.h> -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ struct serial2002_board { const char *name; }; -static const struct serial2002_board serial2002_boards[] = { - { - .name = "serial2002"} -}; - /* * Useful for shorthand access to the particular board structure */ @@ -89,35 +79,6 @@ struct serial2002_private { */ #define devpriv ((struct serial2002_private *)dev->private) -static int serial2002_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int serial2002_detach(struct comedi_device *dev); -struct comedi_driver driver_serial2002 = { - .driver_name = "serial2002", - .module = THIS_MODULE, - .attach = serial2002_attach, - .detach = serial2002_detach, - .board_name = &serial2002_boards[0].name, - .offset = sizeof(struct serial2002_board), - .num_names = ARRAY_SIZE(serial2002_boards), -}; - -static int serial2002_di_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_do_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ai_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int serial2002_ao_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - struct serial_data { enum { is_invalid, is_digital, is_channel } kind; int index; @@ -887,32 +848,34 @@ static int serial2002_attach(struct comedi_device *dev, return 1; } -static int serial2002_detach(struct comedi_device *dev) +static void serial2002_detach(struct comedi_device *dev) { struct comedi_subdevice *s; int i; - dev_dbg(dev->hw_dev, "comedi%d: remove\n", dev->minor); for (i = 0; i < 5; i++) { s = &dev->subdevices[i]; kfree(s->maxdata_list); kfree(s->range_table_list); } - return 0; -} - -static int __init driver_serial2002_init_module(void) -{ - return comedi_driver_register(&driver_serial2002); } -static void __exit driver_serial2002_cleanup_module(void) -{ - comedi_driver_unregister(&driver_serial2002); -} +static const struct serial2002_board serial2002_boards[] = { + { + .name = "serial2002" + }, +}; -module_init(driver_serial2002_init_module); -module_exit(driver_serial2002_cleanup_module); +static struct comedi_driver serial2002_driver = { + .driver_name = "serial2002", + .module = THIS_MODULE, + .attach = serial2002_attach, + .detach = serial2002_detach, + .board_name = &serial2002_boards[0].name, + .offset = sizeof(struct serial2002_board), + .num_names = ARRAY_SIZE(serial2002_boards), +}; +module_comedi_driver(serial2002_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index ed69008..7d13ffa 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -156,7 +156,7 @@ struct skel_private { * the device code. */ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int skel_detach(struct comedi_device *dev); +static void skel_detach(struct comedi_device *dev); static struct comedi_driver driver_skel = { .driver_name = "dummy", .module = THIS_MODULE, @@ -295,11 +295,8 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) * allocated by _attach(). dev->private and dev->subdevices are * deallocated automatically by the core. */ -static int skel_detach(struct comedi_device *dev) +static void skel_detach(struct comedi_device *dev) { - pr_info("comedi%d: skel: remove\n", dev->minor); - - return 0; } /* @@ -623,7 +620,7 @@ static int skel_dio_insn_config(struct comedi_device *dev, static int __devinit driver_skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, driver_skel.driver_name); + return comedi_pci_auto_config(dev, &driver_skel); } static void __devexit driver_skel_pci_remove(struct pci_dev *dev) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index 526de2e..16c4f5a 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -59,16 +59,6 @@ struct dnp_board { int have_dio; }; -/* We only support one DNP 'board' variant at the moment */ -static const struct dnp_board dnp_boards[] = { -{ - .name = "dnp-1486", - .ai_chans = 16, - .ai_bits = 12, - .have_dio = 1, - }, -}; - /* Useful for shorthand access to the particular board structure ----------- */ #define thisboard ((const struct dnp_board *)dev->board_ptr) @@ -81,136 +71,6 @@ struct dnp_private_data { #define devpriv ((dnp_private *)dev->private) /* ------------------------------------------------------------------------- */ -/* The struct comedi_driver structure tells the Comedi core module which */ -/* functions to call to configure/deconfigure (attach/detach) the board, and */ -/* also about the kernel module that contains the device code. */ -/* */ -/* In the following section we define the API of this driver. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static int dnp_detach(struct comedi_device *dev); - -static struct comedi_driver driver_dnp = { - .driver_name = "ssv_dnp", - .module = THIS_MODULE, - .attach = dnp_attach, - .detach = dnp_detach, - .board_name = &dnp_boards[0].name, - /* only necessary for non-PnP devs */ - .offset = sizeof(struct dnp_board), /* like ISA-PnP, PCI or PCMCIA */ - .num_names = ARRAY_SIZE(dnp_boards), -}; - -static int __init driver_dnp_init_module(void) -{ - return comedi_driver_register(&driver_dnp); -} - -static void __exit driver_dnp_cleanup_module(void) -{ - comedi_driver_unregister(&driver_dnp); -} - -module_init(driver_dnp_init_module); -module_exit(driver_dnp_cleanup_module); - -static int dnp_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -static int dnp_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* ------------------------------------------------------------------------- */ -/* Attach is called by comedi core to configure the driver for a particular */ -/* board. If you specified a board_name array in the driver structure, */ -/* dev->board_ptr contains that address. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - - struct comedi_subdevice *s; - - printk(KERN_INFO "comedi%d: dnp: ", dev->minor); - - /* Autoprobing: this should find out which board we have. Currently */ - /* only the 1486 board is supported and autoprobing is not */ - /* implemented :-) */ - /* dev->board_ptr = dnp_probe(dev); */ - - /* Initialize the name of the board. */ - /* We can use the "thisboard" macro now. */ - dev->board_name = thisboard->name; - - /* Allocate the private structure area. alloc_private() is a */ - /* convenient macro defined in comedidev.h. */ - if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) - return -ENOMEM; - - /* Allocate the subdevice structures. alloc_subdevice() is a */ - /* convenient macro defined in comedidev.h. */ - - if (alloc_subdevices(dev, 1) < 0) - return -ENOMEM; - - s = dev->subdevices + 0; - /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 20; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = dnp_dio_insn_bits; - s->insn_config = dnp_dio_insn_config; - - printk("attached\n"); - - /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always - * allocated for the primary 8259, so we don't need to allocate them - * ourselves. */ - - /* configure all ports as input (default) */ - outb(PAMR, CSCIR); - outb(0x00, CSCDR); - outb(PBMR, CSCIR); - outb(0x00, CSCDR); - outb(PCMR, CSCIR); - outb((inb(CSCDR) & 0xAA), CSCDR); - - return 1; - -} - -/* ------------------------------------------------------------------------- */ -/* detach is called to deconfigure a device. It should deallocate the */ -/* resources. This function is also called when _attach() fails, so it */ -/* should be careful not to release resources that were not necessarily */ -/* allocated by _attach(). dev->private and dev->subdevices are */ -/* deallocated automatically by the core. */ -/* ------------------------------------------------------------------------- */ - -static int dnp_detach(struct comedi_device *dev) -{ - - /* configure all ports as input (default) */ - outb(PAMR, CSCIR); - outb(0x00, CSCDR); - outb(PBMR, CSCIR); - outb(0x00, CSCDR); - outb(PCMR, CSCIR); - outb((inb(CSCDR) & 0xAA), CSCDR); - - /* announce that we are finished */ - printk(KERN_INFO "comedi%d: dnp: remove\n", dev->minor); - - return 0; - -} - -/* ------------------------------------------------------------------------- */ /* The insn_bits interface allows packed reading/writing of DIO channels. */ /* The comedi core can convert between insn_bits and insn_read/write, so you */ /* are able to use these instructions as well. */ @@ -326,6 +186,89 @@ static int dnp_dio_insn_config(struct comedi_device *dev, } +static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + + printk(KERN_INFO "comedi%d: dnp: ", dev->minor); + + /* Autoprobing: this should find out which board we have. Currently */ + /* only the 1486 board is supported and autoprobing is not */ + /* implemented :-) */ + /* dev->board_ptr = dnp_probe(dev); */ + + /* Initialize the name of the board. */ + /* We can use the "thisboard" macro now. */ + dev->board_name = thisboard->name; + + /* Allocate the private structure area. alloc_private() is a */ + /* convenient macro defined in comedidev.h. */ + if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0) + return -ENOMEM; + + /* Allocate the subdevice structures. alloc_subdevice() is a */ + /* convenient macro defined in comedidev.h. */ + + if (alloc_subdevices(dev, 1) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* digital i/o subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 20; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = dnp_dio_insn_bits; + s->insn_config = dnp_dio_insn_config; + + printk("attached\n"); + + /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always + * allocated for the primary 8259, so we don't need to allocate them + * ourselves. */ + + /* configure all ports as input (default) */ + outb(PAMR, CSCIR); + outb(0x00, CSCDR); + outb(PBMR, CSCIR); + outb(0x00, CSCDR); + outb(PCMR, CSCIR); + outb((inb(CSCDR) & 0xAA), CSCDR); + + return 1; +} + +static void dnp_detach(struct comedi_device *dev) +{ + outb(PAMR, CSCIR); + outb(0x00, CSCDR); + outb(PBMR, CSCIR); + outb(0x00, CSCDR); + outb(PCMR, CSCIR); + outb((inb(CSCDR) & 0xAA), CSCDR); +} + +static const struct dnp_board dnp_boards[] = { + { + .name = "dnp-1486", + .ai_chans = 16, + .ai_bits = 12, + .have_dio = 1, + }, +}; + +static struct comedi_driver dnp_driver = { + .driver_name = "ssv_dnp", + .module = THIS_MODULE, + .attach = dnp_attach, + .detach = dnp_detach, + .board_name = &dnp_boards[0].name, + .offset = sizeof(struct dnp_board), + .num_names = ARRAY_SIZE(dnp_boards), +}; +module_comedi_driver(dnp_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index f45824f..d5f1f22 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -83,96 +83,188 @@ struct unioxx5_subd_priv { unsigned char usp_prev_cn_val[3]; /* previous channel value */ }; -static int unioxx5_attach(struct comedi_device *dev, - struct comedi_devconfig *it); -static int unioxx5_subdev_write(struct comedi_device *dev, - struct comedi_subdevice *subdev, - struct comedi_insn *insn, unsigned int *data); -static int unioxx5_subdev_read(struct comedi_device *dev, - struct comedi_subdevice *subdev, - struct comedi_insn *insn, unsigned int *data); -static int unioxx5_insn_config(struct comedi_device *dev, - struct comedi_subdevice *subdev, - struct comedi_insn *insn, unsigned int *data); -static int unioxx5_detach(struct comedi_device *dev); -static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, - int subdev_iobase, int minor); -static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor); -static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor); -/* static void __unioxx5_digital_config(struct unioxx5_subd_priv* usp, int mode); */ -static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor); -static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor); -static int __unioxx5_define_chan_offset(int chan_num); -static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel); +static int __unioxx5_define_chan_offset(int chan_num) +{ -static struct comedi_driver unioxx5_driver = { - .driver_name = DRIVER_NAME, - .module = THIS_MODULE, - .attach = unioxx5_attach, - .detach = unioxx5_detach -}; + if (chan_num < 0 || chan_num > 23) + return -1; -static int __init unioxx5_driver_init_module(void) + return (chan_num >> 3) + 1; +} + +#if 0 /* not used? */ +static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode) { - return comedi_driver_register(&unioxx5_driver); + int i, mask; + + mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00; + printk("COMEDI: mode = %d\n", mask); + + outb(1, usp->usp_iobase + 0); + + for (i = 0; i < 3; i++) + outb(mask, usp->usp_iobase + i); + + outb(0, usp->usp_iobase + 0); } +#endif -static void __exit unioxx5_driver_cleanup_module(void) +/* configure channels for analog i/o (even to output, odd to input) */ +static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel) { - comedi_driver_unregister(&unioxx5_driver); + int chan_a, chan_b, conf, channel_offset; + + channel_offset = __unioxx5_define_chan_offset(channel); + conf = usp->usp_prev_cn_val[channel_offset - 1]; + chan_a = chan_b = 1; + + /* setting channel A and channel B mask */ + if (channel % 2 == 0) { + chan_a <<= channel & 0x07; + chan_b <<= (channel + 1) & 0x07; + } else { + chan_a <<= (channel - 1) & 0x07; + chan_b <<= channel & 0x07; + } + + conf |= chan_a; /* even channel ot output */ + conf &= ~chan_b; /* odd channel to input */ + + outb(1, usp->usp_iobase + 0); + outb(conf, usp->usp_iobase + channel_offset); + outb(0, usp->usp_iobase + 0); + + usp->usp_prev_cn_val[channel_offset - 1] = conf; } -module_init(unioxx5_driver_init_module); -module_exit(unioxx5_driver_cleanup_module); +static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, + unsigned int *data, int channel, int minor) +{ + int channel_offset, mask = 1 << (channel & 0x07); -static int unioxx5_attach(struct comedi_device *dev, - struct comedi_devconfig *it) + channel_offset = __unioxx5_define_chan_offset(channel); + if (channel_offset < 0) { + printk(KERN_ERR + "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + minor, channel); + return 0; + } + + *data = inb(usp->usp_iobase + channel_offset); + *data &= mask; + + /* correct the read value to 0 or 1 */ + if (channel_offset > 1) + channel -= 2 << channel_offset; + *data >>= channel; + return 1; +} + +static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, + unsigned int *data, int channel, int minor) { - int iobase, i, n_subd; - int id, num, ba; + int module_no, read_ch; + char control; - iobase = it->options[0]; + module_no = channel / 2; + read_ch = channel % 2; /* depend on type of channel (A or B) */ - dev->board_name = DRIVER_NAME; - dev->iobase = iobase; - iobase += UNIOXX5_SUBDEV_BASE; + /* defining if given module can work on input */ + if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { + printk(KERN_ERR + "comedi%d: module in position %d with id 0x%02x is for output only", + minor, module_no, usp->usp_module_type[module_no]); + return 0; + } - /* defining number of subdevices and getting they types (it must be 'g01') */ - for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { - id = inb(ba + 0xE); - num = inb(ba + 0xF); + __unioxx5_analog_config(usp, channel); + /* sends module number to card(1 .. 12) */ + outb(module_no + 1, usp->usp_iobase + 5); + outb('V', usp->usp_iobase + 6); /* sends to module (V)erify command */ + control = inb(usp->usp_iobase); /* get control register byte */ - if (id != 'g' || num != 1) - continue; + /* waits while reading four bytes will be allowed */ + while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) + ; - n_subd++; + /* if four bytes readding error occurs - return 0(false) */ + if ((control & Rx4CA_ERR_MASK)) { + printk("COMEDI: 4 bytes error\n"); + return 0; } - /* unioxx5 can has from two to four subdevices */ - if (n_subd < 2) { + if (read_ch) + *data = inw(usp->usp_iobase + 6); /* channel B */ + else + *data = inw(usp->usp_iobase + 4); /* channel A */ + + return 1; +} + +static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, + unsigned int *data, int channel, int minor) +{ + int channel_offset, val; + int mask = 1 << (channel & 0x07); + + channel_offset = __unioxx5_define_chan_offset(channel); + if (channel_offset < 0) { printk(KERN_ERR - "your card must has at least 2 'g01' subdevices\n"); - return -1; + "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + minor, channel); + return 0; } - if (alloc_subdevices(dev, n_subd) < 0) { - printk(KERN_ERR "out of memory\n"); - return -ENOMEM; + /* getting previous written value */ + val = usp->usp_prev_wr_val[channel_offset - 1]; + + if (*data) + val |= mask; + else + val &= ~mask; + + outb(val, usp->usp_iobase + channel_offset); + /* saving new written value */ + usp->usp_prev_wr_val[channel_offset - 1] = val; + + return 1; +} + +static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, + unsigned int *data, int channel, int minor) +{ + int module, i; + + module = channel / 2; /* definig module number(0 .. 11) */ + i = (channel % 2) << 1; /* depends on type of channel (A or B) */ + + /* defining if given module can work on output */ + if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { + printk(KERN_ERR + "comedi%d: module in position %d with id 0x%0x is for input only!\n", + minor, module, usp->usp_module_type[module]); + return 0; } - /* initializing each of for same subdevices */ - for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { - if (__unioxx5_subdev_init(&dev->subdevices[i], iobase, - dev->minor) < 0) - return -1; + __unioxx5_analog_config(usp, channel); + /* saving minor byte */ + usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF); + /* saving major byte */ + usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8); + + /* while(!((inb(usp->usp_iobase + 0)) & TxBE)); */ + /* sending module number to card(1 .. 12) */ + outb(module + 1, usp->usp_iobase + 5); + outb('W', usp->usp_iobase + 6); /* sends (W)rite command to module */ + + /* sending for bytes to module(one byte per cycle iteration) */ + for (i = 0; i < 4; i++) { + while (!((inb(usp->usp_iobase + 0)) & TxBE)) + ; /* waits while writting will be allowed */ + outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6); } - printk(KERN_INFO "attached\n"); - return 0; + return 1; } static int unioxx5_subdev_read(struct comedi_device *dev, @@ -275,22 +367,6 @@ static int unioxx5_insn_config(struct comedi_device *dev, return 0; } -static int unioxx5_detach(struct comedi_device *dev) -{ - int i; - struct comedi_subdevice *subdev; - struct unioxx5_subd_priv *usp; - - for (i = 0; i < dev->n_subdevices; i++) { - subdev = &dev->subdevices[i]; - usp = subdev->private; - release_region(usp->usp_iobase, UNIOXX5_SIZE); - kfree(subdev->private); - } - - return 0; -} - /* initializing subdevice with given address */ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int subdev_iobase, int minor) @@ -362,196 +438,73 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, return 0; } -static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor) +static int unioxx5_attach(struct comedi_device *dev, + struct comedi_devconfig *it) { - int channel_offset, val; - int mask = 1 << (channel & 0x07); - - channel_offset = __unioxx5_define_chan_offset(channel); - if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); - return 0; - } - - /* getting previous written value */ - val = usp->usp_prev_wr_val[channel_offset - 1]; + int iobase, i, n_subd; + int id, num, ba; - if (*data) - val |= mask; - else - val &= ~mask; + iobase = it->options[0]; - outb(val, usp->usp_iobase + channel_offset); - /* saving new written value */ - usp->usp_prev_wr_val[channel_offset - 1] = val; + dev->board_name = DRIVER_NAME; + dev->iobase = iobase; + iobase += UNIOXX5_SUBDEV_BASE; - return 1; -} + /* defining number of subdevices and getting they types (it must be 'g01') */ + for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { + id = inb(ba + 0xE); + num = inb(ba + 0xF); -/* function for digital reading */ -static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor) -{ - int channel_offset, mask = 1 << (channel & 0x07); + if (id != 'g' || num != 1) + continue; - channel_offset = __unioxx5_define_chan_offset(channel); - if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); - return 0; + n_subd++; } - *data = inb(usp->usp_iobase + channel_offset); - *data &= mask; - - if (channel_offset > 1) - channel -= 2 << channel_offset; /* this operation is created for correct readed value to 0 or 1 */ - *data >>= channel; - return 1; -} - -#if 0 /* not used? */ -static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode) -{ - int i, mask; - - mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00; - printk("COMEDI: mode = %d\n", mask); - - outb(1, usp->usp_iobase + 0); - - for (i = 0; i < 3; i++) - outb(mask, usp->usp_iobase + i); - - outb(0, usp->usp_iobase + 0); -} -#endif - -static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor) -{ - int module, i; - - module = channel / 2; /* definig module number(0 .. 11) */ - i = (channel % 2) << 1; /* depends on type of channel (A or B) */ - - /* defining if given module can work on output */ - if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { + /* unioxx5 can has from two to four subdevices */ + if (n_subd < 2) { printk(KERN_ERR - "comedi%d: module in position %d with id 0x%0x is for input only!\n", - minor, module, usp->usp_module_type[module]); - return 0; - } - - __unioxx5_analog_config(usp, channel); - /* saving minor byte */ - usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF); - /* saving major byte */ - usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8); - - /* while(!((inb(usp->usp_iobase + 0)) & TxBE)); */ - /* sending module number to card(1 .. 12) */ - outb(module + 1, usp->usp_iobase + 5); - outb('W', usp->usp_iobase + 6); /* sends (W)rite command to module */ - - /* sending for bytes to module(one byte per cycle iteration) */ - for (i = 0; i < 4; i++) { - while (!((inb(usp->usp_iobase + 0)) & TxBE)) - ; /* waits while writting will be allowed */ - outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6); + "your card must has at least 2 'g01' subdevices\n"); + return -1; } - return 1; -} - -static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, - unsigned int *data, int channel, int minor) -{ - int module_no, read_ch; - char control; - - module_no = channel / 2; - read_ch = channel % 2; /* depend on type of channel (A or B) */ - - /* defining if given module can work on input */ - if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { - printk(KERN_ERR - "comedi%d: module in position %d with id 0x%02x is for output only", - minor, module_no, usp->usp_module_type[module_no]); - return 0; + if (alloc_subdevices(dev, n_subd) < 0) { + printk(KERN_ERR "out of memory\n"); + return -ENOMEM; } - __unioxx5_analog_config(usp, channel); - /* sends module number to card(1 .. 12) */ - outb(module_no + 1, usp->usp_iobase + 5); - outb('V', usp->usp_iobase + 6); /* sends to module (V)erify command */ - control = inb(usp->usp_iobase); /* get control register byte */ - - /* waits while reading four bytes will be allowed */ - while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) - ; - - /* if four bytes readding error occurs - return 0(false) */ - if ((control & Rx4CA_ERR_MASK)) { - printk("COMEDI: 4 bytes error\n"); - return 0; + /* initializing each of for same subdevices */ + for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) { + if (__unioxx5_subdev_init(&dev->subdevices[i], iobase, + dev->minor) < 0) + return -1; } - if (read_ch) - *data = inw(usp->usp_iobase + 6); /* channel B */ - else - *data = inw(usp->usp_iobase + 4); /* channel A */ - - return 1; + printk(KERN_INFO "attached\n"); + return 0; } -/* configure channels for analog i/o (even to output, odd to input) */ -static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel) +static void unioxx5_detach(struct comedi_device *dev) { - int chan_a, chan_b, conf, channel_offset; - - channel_offset = __unioxx5_define_chan_offset(channel); - conf = usp->usp_prev_cn_val[channel_offset - 1]; - chan_a = chan_b = 1; + int i; + struct comedi_subdevice *subdev; + struct unioxx5_subd_priv *usp; - /* setting channel A and channel B mask */ - if (channel % 2 == 0) { - chan_a <<= channel & 0x07; - chan_b <<= (channel + 1) & 0x07; - } else { - chan_a <<= (channel - 1) & 0x07; - chan_b <<= channel & 0x07; + for (i = 0; i < dev->n_subdevices; i++) { + subdev = &dev->subdevices[i]; + usp = subdev->private; + release_region(usp->usp_iobase, UNIOXX5_SIZE); + kfree(subdev->private); } - - conf |= chan_a; /* even channel ot output */ - conf &= ~chan_b; /* odd channel to input */ - - outb(1, usp->usp_iobase + 0); - outb(conf, usp->usp_iobase + channel_offset); - outb(0, usp->usp_iobase + 0); - - usp->usp_prev_cn_val[channel_offset - 1] = conf; } -/* *\ - * this function defines if the given channel number * - * enters in default numeric interspace(from 0 to 23) * - * and it returns address offset for usage needed * - * channel. * -\* */ - -static int __unioxx5_define_chan_offset(int chan_num) -{ - - if (chan_num < 0 || chan_num > 23) - return -1; - - return (chan_num >> 3) + 1; -} +static struct comedi_driver unioxx5_driver = { + .driver_name = DRIVER_NAME, + .module = THIS_MODULE, + .attach = unioxx5_attach, + .detach = unioxx5_detach, +}; +module_comedi_driver(unioxx5_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index bf62e0d..13d9fd3 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -317,6 +317,8 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbdux; /* see below for initializer */ + /* * Stops the data acquision * It should be safe to call this function from any context @@ -2304,11 +2306,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2320,11 +2322,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(uinterf, &driver_usbdux); out: release_firmware(fw); } @@ -2606,7 +2608,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n"); return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); @@ -2615,46 +2617,21 @@ static void usbduxsub_disconnect(struct usb_interface *intf) dev_dbg(&intf->dev, "comedi_: disconnected from the usb\n"); } -/* is called when comedi-config is called */ -static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) +/* common part of attach and attach_usb */ +static int usbdux_attach_common(struct comedi_device *dev, + struct usbduxsub *udev, + void *aux_data, int aux_len) { int ret; - int index; - int i; - struct usbduxsub *udev; - struct comedi_subdevice *s = NULL; - dev->private = NULL; - - down(&start_stop_sem); - /* find a valid device which has been detected by the probe function of - * the usb */ - index = -1; - for (i = 0; i < NUMUSBDUX; i++) { - if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { - index = i; - break; - } - } - if (index < 0) { - printk(KERN_ERR "comedi%d: usbdux: error: attach failed, no " - "usbdux devs connected to the usb bus.\n", dev->minor); - up(&start_stop_sem); - return -ENODEV; - } - - udev = &usbduxsub[index]; down(&udev->sem); /* pointer back to the corresponding comedi device */ udev->comedidev = dev; /* trying to upload the firmware into the chip */ - if (comedi_aux_data(it->options, 0) && - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { - firmwareUpload(udev, comedi_aux_data(it->options, 0), - it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } + if (aux_data) + firmwareUpload(udev, aux_data, aux_len); dev->board_name = BOARDNAME; @@ -2673,13 +2650,9 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_err(&udev->interface->dev, "comedi%d: error alloc space for subdev\n", dev->minor); up(&udev->sem); - up(&start_stop_sem); return ret; } - dev_info(&udev->interface->dev, - "comedi%d: usb-device %d is attached to comedi.\n", - dev->minor, index); /* private structure is also simply the usb-structure */ dev->private = udev; @@ -2776,44 +2749,91 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) up(&udev->sem); - up(&start_stop_sem); - dev_info(&udev->interface->dev, "comedi%d: attached to usbdux.\n", dev->minor); return 0; } -static int usbdux_detach(struct comedi_device *dev) +/* is called when comedi-config is called */ +static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - struct usbduxsub *usbduxsub_tmp; + int ret; + int index; + int i; + void *aux_data; + int aux_len; - if (!dev) { - printk(KERN_ERR - "comedi?: usbdux: detach without dev variable...\n"); - return -EFAULT; + dev->private = NULL; + + aux_data = comedi_aux_data(it->options, 0); + aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]; + if (aux_data == NULL) + aux_len = 0; + else if (aux_len == 0) + aux_data = NULL; + + down(&start_stop_sem); + /* find a valid device which has been detected by the probe function of + * the usb */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { + index = i; + break; + } } - usbduxsub_tmp = dev->private; - if (!usbduxsub_tmp) { + if (index < 0) { printk(KERN_ERR - "comedi?: usbdux: detach without ptr to usbduxsub[]\n"); - return -EFAULT; - } + "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n", + dev->minor); + ret = -ENODEV; + } else + ret = usbdux_attach_common(dev, &usbduxsub[index], + aux_data, aux_len); + up(&start_stop_sem); + return ret; +} - dev_dbg(&usbduxsub_tmp->interface->dev, "comedi%d: detach usb device\n", - dev->minor); +/* is called from comedi_usb_auto_config() */ +static int usbdux_attach_usb(struct comedi_device *dev, + struct usb_interface *uinterf) +{ + int ret; + struct usbduxsub *this_usbduxsub; - down(&usbduxsub_tmp->sem); - /* Don't allow detach to free the private structure */ - /* It's one entry of of usbduxsub[] */ dev->private = NULL; - usbduxsub_tmp->attached = 0; - usbduxsub_tmp->comedidev = NULL; - dev_dbg(&usbduxsub_tmp->interface->dev, - "comedi%d: detach: successfully removed\n", dev->minor); - up(&usbduxsub_tmp->sem); - return 0; + + down(&start_stop_sem); + this_usbduxsub = usb_get_intfdata(uinterf); + if (!this_usbduxsub || !this_usbduxsub->probed) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, not connected\n", + dev->minor); + ret = -ENODEV; + } else if (this_usbduxsub->attached) { + printk(KERN_ERR + "comedi%d: usbdux: error: attach_usb failed, already attached\n", + dev->minor); + ret = -ENODEV; + } else + ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0); + up(&start_stop_sem); + return ret; +} + +static void usbdux_detach(struct comedi_device *dev) +{ + struct usbduxsub *usb = dev->private; + + if (usb) { + down(&usb->sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&usb->sem); + } } /* main driver struct */ @@ -2822,6 +2842,7 @@ static struct comedi_driver driver_usbdux = { .module = THIS_MODULE, .attach = usbdux_attach, .detach = usbdux_detach, + .attach_usb = usbdux_attach_usb, }; /* Table with the USB-devices: just now only testing IDs */ diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 2a8e725..7b1d21a 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -201,6 +201,8 @@ static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbduxfast; /* see below for initializer */ + /* * bulk transfers to usbduxfast */ @@ -453,14 +455,15 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) /* 7f92 to zero */ local_transfer_buffer[0] = 0; /* bRequest, "Firmware" */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, - VENDOR_DIR_OUT, /* bmRequestType */ - USBDUXFASTSUB_CPUCS, /* Value */ - 0x0000, /* Index */ - /* address of the transfer buffer */ - local_transfer_buffer, - 1, /* Length */ - EZTIMEOUT); /* Timeout */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + USBDUXFASTSUB_CPUCS, /* Value */ + 0x0000, /* Index */ + /* address of the transfer buffer */ + local_transfer_buffer, + 1, /* Length */ + EZTIMEOUT); /* Timeout */ if (ret < 0) { printk("comedi_: usbduxfast_: control msg failed (start)\n"); return ret; @@ -477,7 +480,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) /* 7f92 to one */ local_transfer_buffer[0] = 1; /* bRequest, "Firmware" */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, VENDOR_DIR_OUT, /* bmRequestType */ USBDUXFASTSUB_CPUCS, /* Value */ 0x0000, /* Index */ @@ -504,14 +508,15 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, startAddr, local_transfer_buffer[0]); #endif /* brequest, firmware */ - ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, - VENDOR_DIR_OUT, /* bmRequestType */ - startAddr, /* value */ - 0x0000, /* index */ - /* our local safe buffer */ - local_transfer_buffer, - len, /* length */ - EZTIMEOUT); /* timeout */ + ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), + USBDUXFASTSUB_FIRMWARE, + VENDOR_DIR_OUT, /* bmRequestType */ + startAddr, /* value */ + 0x0000, /* index */ + /* our local safe buffer */ + local_transfer_buffer, + len, /* length */ + EZTIMEOUT); /* timeout */ #ifdef CONFIG_COMEDI_DEBUG printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret); @@ -1440,7 +1445,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxfastsub_s *usbduxfastsub_tmp = context; - struct usb_device *usbdev = usbduxfastsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxfastsub_tmp->interface; int ret; if (fw == NULL) @@ -1453,12 +1458,12 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware ret = firmwareUpload(usbduxfastsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(uinterf, &driver_usbduxfast); out: release_firmware(fw); } @@ -1606,7 +1611,7 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) return; } - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&udfs->sem); @@ -1721,43 +1726,19 @@ static int usbduxfast_attach(struct comedi_device *dev, return 0; } -static int usbduxfast_detach(struct comedi_device *dev) +static void usbduxfast_detach(struct comedi_device *dev) { - struct usbduxfastsub_s *udfs; - - if (!dev) { - printk(KERN_ERR "comedi?: usbduxfast: detach without dev " - "variable...\n"); - return -EFAULT; - } -#ifdef CONFIG_COMEDI_DEBUG - printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n", - dev->minor); -#endif - - udfs = dev->private; - if (!udfs) { - printk(KERN_ERR "comedi?: usbduxfast: detach without ptr to " - "usbduxfastsub[]\n"); - return -EFAULT; + struct usbduxfastsub_s *usb = dev->private; + + if (usb) { + down(&usb->sem); + down(&start_stop_sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&start_stop_sem); + up(&usb->sem); } - - down(&udfs->sem); - down(&start_stop_sem); - /* - * Don't allow detach to free the private structure - * It's one entry of of usbduxfastsub[] - */ - dev->private = NULL; - udfs->attached = 0; - udfs->comedidev = NULL; -#ifdef CONFIG_COMEDI_DEBUG - printk(KERN_DEBUG "comedi%d: usbduxfast: detach: successfully " - "removed\n", dev->minor); -#endif - up(&start_stop_sem); - up(&udfs->sem); - return 0; } /* diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 63c9b6d..465afbd 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -267,6 +267,8 @@ static struct usbduxsub usbduxsub[NUMUSBDUX]; static DEFINE_SEMAPHORE(start_stop_sem); +static struct comedi_driver driver_usbduxsigma; /* see below for initializer */ + /* * Stops the data acquision * It should be safe to call this function from any context @@ -2312,11 +2314,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, void *context) { struct usbduxsub *usbduxsub_tmp = context; - struct usb_device *usbdev = usbduxsub_tmp->usbdev; + struct usb_interface *uinterf = usbduxsub_tmp->interface; int ret; if (fw == NULL) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Firmware complete handler without firmware!\n"); return; } @@ -2328,11 +2330,11 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw, ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); if (ret) { - dev_err(&usbdev->dev, + dev_err(&uinterf->dev, "Could not upload firmware (err=%d)\n", ret); goto out; } - comedi_usb_auto_config(usbdev, BOARDNAME); + comedi_usb_auto_config(uinterf, &driver_usbduxsigma); out: release_firmware(fw); } @@ -2623,7 +2625,7 @@ static void usbduxsigma_disconnect(struct usb_interface *intf) if (usbduxsub_tmp->ao_cmd_running) /* we are still running a command */ usbdux_ao_stop(usbduxsub_tmp, 1); - comedi_usb_auto_unconfig(udev); + comedi_usb_auto_unconfig(intf); down(&start_stop_sem); down(&usbduxsub_tmp->sem); tidy_up(usbduxsub_tmp); @@ -2799,37 +2801,17 @@ static int usbduxsigma_attach(struct comedi_device *dev, return 0; } -static int usbduxsigma_detach(struct comedi_device *dev) +static void usbduxsigma_detach(struct comedi_device *dev) { - struct usbduxsub *usbduxsub_tmp; + struct usbduxsub *usb = dev->private; - if (!dev) { - printk(KERN_ERR - "comedi? usbduxsigma detach: dev=NULL\n"); - return -EFAULT; + if (usb) { + down(&usb->sem); + dev->private = NULL; + usb->attached = 0; + usb->comedidev = NULL; + up(&usb->sem); } - - usbduxsub_tmp = dev->private; - if (!usbduxsub_tmp) { - printk(KERN_ERR - "comedi?: usbduxsigma detach: private=NULL\n"); - return -EFAULT; - } - - dev_dbg(&usbduxsub_tmp->interface->dev, - "comedi%d: detach usb device\n", - dev->minor); - - down(&usbduxsub_tmp->sem); - /* Don't allow detach to free the private structure */ - /* It's one entry of of usbduxsub[] */ - dev->private = NULL; - usbduxsub_tmp->attached = 0; - usbduxsub_tmp->comedidev = NULL; - dev_info(&usbduxsub_tmp->interface->dev, - "comedi%d: successfully detached.\n", dev->minor); - up(&usbduxsub_tmp->sem); - return 0; } /* main driver struct */ diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 2dba3ef..baee8d7 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -151,27 +151,12 @@ MODULE_DEVICE_TABLE(usb, vmk80xx_id_table); #define URB_RCV_FLAG (1 << 0) #define URB_SND_FLAG (1 << 1) -#define CONFIG_VMK80XX_DEBUG -#undef CONFIG_VMK80XX_DEBUG - -#ifdef CONFIG_VMK80XX_DEBUG -static int dbgvm = 1; -#else -static int dbgvm; -#endif - #ifdef CONFIG_COMEDI_DEBUG static int dbgcm = 1; #else static int dbgcm; #endif -#define dbgvm(fmt, arg...) \ -do { \ - if (dbgvm) \ - printk(KERN_DEBUG fmt, ##arg); \ -} while (0) - #define dbgcm(fmt, arg...) \ do { \ if (dbgcm) \ @@ -247,13 +232,13 @@ static struct vmk80xx_usb vmb[VMK80XX_MAX_BOARDS]; static DEFINE_MUTEX(glb_mutex); +static struct comedi_driver driver_vmk80xx; /* see below for initializer */ + static void vmk80xx_tx_callback(struct urb *urb) { struct vmk80xx_usb *dev = urb->context; int stat = urb->status; - dbgvm("vmk80xx: %s\n", __func__); - if (stat && !(stat == -ENOENT || stat == -ECONNRESET || stat == -ESHUTDOWN)) dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n", @@ -272,8 +257,6 @@ static void vmk80xx_rx_callback(struct urb *urb) struct vmk80xx_usb *dev = urb->context; int stat = urb->status; - dbgvm("vmk80xx: %s\n", __func__); - switch (stat) { case 0: break; @@ -314,8 +297,6 @@ static int vmk80xx_check_data_link(struct vmk80xx_usb *dev) unsigned char tx[1]; unsigned char rx[2]; - dbgvm("vmk80xx: %s\n", __func__); - tx_pipe = usb_sndbulkpipe(dev->udev, 0x01); rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81); @@ -340,8 +321,6 @@ static void vmk80xx_read_eeprom(struct vmk80xx_usb *dev, int flag) unsigned char rx[64]; int cnt; - dbgvm("vmk80xx: %s\n", __func__); - tx_pipe = usb_sndbulkpipe(dev->udev, 0x01); rx_pipe = usb_rcvbulkpipe(dev->udev, 0x81); @@ -369,8 +348,6 @@ static int vmk80xx_reset_device(struct vmk80xx_usb *dev) int ival; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) return -ENOMEM; @@ -408,8 +385,6 @@ static void vmk80xx_build_int_urb(struct urb *urb, int flag) void (*callback) (struct urb *); int ival; - dbgvm("vmk80xx: %s\n", __func__); - if (flag & URB_RCV_FLAG) { rx_addr = dev->ep_rx->bEndpointAddress; pipe = usb_rcvintpipe(dev->udev, rx_addr); @@ -437,8 +412,6 @@ static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev) unsigned int rx_pipe; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - set_bit(TRANS_IN_BUSY, &dev->flags); set_bit(TRANS_OUT_BUSY, &dev->flags); @@ -466,8 +439,6 @@ static int vmk80xx_read_packet(struct vmk80xx_usb *dev) struct urb *urb; int retval; - dbgvm("vmk80xx: %s\n", __func__); - if (!dev->intf) return -ENODEV; @@ -514,8 +485,6 @@ static int vmk80xx_write_packet(struct vmk80xx_usb *dev, int cmd) struct urb *urb; int retval; - dbgvm("vmk80xx: %s\n", __func__); - if (!dev->intf) return -ENODEV; @@ -590,8 +559,6 @@ static int vmk80xx_ai_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -643,8 +610,6 @@ static int vmk80xx_ao_winsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -688,8 +653,6 @@ static int vmk80xx_ao_rinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -722,8 +685,6 @@ static int vmk80xx_di_bits(struct comedi_device *cdev, int reg; int retval; - dbgvm("vmk80xx: %s\n", __func__); - retval = rudimentary_check(dev, DIR_IN); if (retval) return retval; @@ -768,8 +729,6 @@ static int vmk80xx_di_rinsn(struct comedi_device *cdev, int inp; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -815,8 +774,6 @@ static int vmk80xx_do_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -863,8 +820,6 @@ static int vmk80xx_do_rinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -897,8 +852,6 @@ static int vmk80xx_do_bits(struct comedi_device *cdev, int dir, reg, cmd; int retval; - dbgvm("vmk80xx: %s\n", __func__); - dir = 0; if (data[0]) @@ -964,8 +917,6 @@ static int vmk80xx_cnt_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -1014,18 +965,16 @@ static int vmk80xx_cnt_cinsn(struct comedi_device *cdev, int reg; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; - down(&dev->limit_sem); - insn_cmd = data[0]; if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET) return -EINVAL; + down(&dev->limit_sem); + chan = CR_CHAN(insn->chanspec); if (dev->board.model == VMK8055_MODEL) { @@ -1062,8 +1011,6 @@ static int vmk80xx_cnt_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -1108,8 +1055,6 @@ static int vmk80xx_pwm_rinsn(struct comedi_device *cdev, int reg[2]; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_IN); if (n) return n; @@ -1143,8 +1088,6 @@ static int vmk80xx_pwm_winsn(struct comedi_device *cdev, int cmd; int n; - dbgvm("vmk80xx: %s\n", __func__); - n = rudimentary_check(dev, DIR_OUT); if (n) return n; @@ -1193,8 +1136,6 @@ static int vmk80xx_attach(struct comedi_device *cdev, struct comedi_subdevice *s; int minor; - dbgvm("vmk80xx: %s\n", __func__); - mutex_lock(&glb_mutex); for (i = 0; i < VMK80XX_MAX_BOARDS; i++) @@ -1309,34 +1250,16 @@ static int vmk80xx_attach(struct comedi_device *cdev, return 0; } -static int vmk80xx_detach(struct comedi_device *cdev) +static void vmk80xx_detach(struct comedi_device *dev) { - struct vmk80xx_usb *dev; - int minor; - - dbgvm("vmk80xx: %s\n", __func__); - - if (!cdev) - return -EFAULT; - - dev = cdev->private; - if (!dev) - return -EFAULT; + struct vmk80xx_usb *usb = dev->private; - down(&dev->limit_sem); - - cdev->private = NULL; - dev->attached = 0; - - minor = cdev->minor; - - printk(KERN_INFO - "comedi%d: vmk80xx: board #%d [%s] detached from comedi\n", - minor, dev->count, dev->board.name); - - up(&dev->limit_sem); - - return 0; + if (usb) { + down(&usb->limit_sem); + dev->private = NULL; + usb->attached = 0; + up(&usb->limit_sem); + } } static int vmk80xx_probe(struct usb_interface *intf, @@ -1348,8 +1271,6 @@ static int vmk80xx_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *ep_desc; size_t size; - dbgvm("vmk80xx: %s\n", __func__); - mutex_lock(&glb_mutex); for (i = 0; i < VMK80XX_MAX_BOARDS; i++) @@ -1484,7 +1405,7 @@ static int vmk80xx_probe(struct usb_interface *intf, mutex_unlock(&glb_mutex); - comedi_usb_auto_config(dev->udev, BOARDNAME); + comedi_usb_auto_config(intf, &driver_vmk80xx); return 0; error: @@ -1497,12 +1418,10 @@ static void vmk80xx_disconnect(struct usb_interface *intf) { struct vmk80xx_usb *dev = usb_get_intfdata(intf); - dbgvm("vmk80xx: %s\n", __func__); - if (!dev) return; - comedi_usb_auto_unconfig(dev->udev); + comedi_usb_auto_unconfig(intf); mutex_lock(&glb_mutex); down(&dev->limit_sem); diff --git a/drivers/staging/comedi/internal.h b/drivers/staging/comedi/internal.h index 434ce34..7ed20a0 100644 --- a/drivers/staging/comedi/internal.h +++ b/drivers/staging/comedi/internal.h @@ -1,5 +1,5 @@ /* - * various internal comedi functions + * various internal comedi stuff */ int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo __user *arg); @@ -7,6 +7,10 @@ int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); int comedi_alloc_board_minor(struct device *hardware_device); void comedi_free_board_minor(unsigned minor); +int comedi_find_board_minor(struct device *hardware_device); void comedi_reset_async_buf(struct comedi_async *async); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); + +extern unsigned int comedi_default_buf_size_kb; +extern unsigned int comedi_default_buf_maxsize_kb; diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 886f565..5b11c5e 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1710,7 +1710,8 @@ static int et131x_mdio_read(struct mii_bus *bus, int phy_addr, int reg) return value; } -static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, int reg, u16 value) +static int et131x_mdio_write(struct mii_bus *bus, int phy_addr, + int reg, u16 value) { struct net_device *netdev = bus->priv; struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4013,7 +4014,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter, dev_err(&pdev->dev, "Missing PCIe capabilities\n"); goto err_out; } - + /* Let's set up the PORT LOGIC Register. First we need to know what * the max_payload_size is */ @@ -4060,7 +4061,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter, goto err_out; } - ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | ( 0x04 << 12); + ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | (0x04 << 12); if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) { dev_err(&pdev->dev, @@ -4824,7 +4825,8 @@ static int et131x_open(struct net_device *netdev) adapter->error_timer.data = (unsigned long)adapter; add_timer(&adapter->error_timer); - result = request_irq(irq, et131x_isr, IRQF_SHARED, netdev->name, netdev); + result = request_irq(irq, et131x_isr, + IRQF_SHARED, netdev->name, netdev); if (result) { dev_err(&pdev->dev, "could not register IRQ %d\n", irq); return result; diff --git a/drivers/staging/gdm72xx/Kconfig b/drivers/staging/gdm72xx/Kconfig new file mode 100644 index 0000000..3c18efe --- /dev/null +++ b/drivers/staging/gdm72xx/Kconfig @@ -0,0 +1,46 @@ +# +# GCT GDM72xx WiMAX driver configuration +# + +menuconfig WIMAX_GDM72XX + tristate "GCT GDM72xx WiMAX support" + depends on NET + help + Support for the GCT GDM72xx WiMAX chip + +if WIMAX_GDM72XX + +config WIMAX_GDM72XX_QOS + bool "Enable QoS support" + default n + +config WIMAX_GDM72XX_K_MODE + bool "Enable K mode" + default n + +config WIMAX_GDM72XX_WIMAX2 + bool "Enable WIMAX2 support" + default n + +choice + prompt "Select interface" + +config WIMAX_GDM72XX_USB + bool "USB interface" + depends on USB + +config WIMAX_GDM72XX_SDIO + bool "SDIO interface" + depends on MMC + +endchoice + +if WIMAX_GDM72XX_USB + +config WIMAX_GDM72XX_USB_PM + bool "Enable power managerment support" + depends on USB_SUSPEND + +endif # WIMAX_GDM72XX_USB + +endif # WIMAX_GDM72XX diff --git a/drivers/staging/gdm72xx/Makefile b/drivers/staging/gdm72xx/Makefile new file mode 100644 index 0000000..35da7b9 --- /dev/null +++ b/drivers/staging/gdm72xx/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_WIMAX_GDM72XX) := gdmwm.o + +gdmwm-y += gdm_wimax.o netlink_k.o +gdmwm-$(CONFIG_WIMAX_GDM72XX_QOS) += gdm_qos.o +gdmwm-$(CONFIG_WIMAX_GDM72XX_SDIO) += gdm_sdio.o sdio_boot.o +gdmwm-$(CONFIG_WIMAX_GDM72XX_USB) += gdm_usb.o usb_boot.o diff --git a/drivers/staging/gdm72xx/TODO b/drivers/staging/gdm72xx/TODO new file mode 100644 index 0000000..30ac01a --- /dev/null +++ b/drivers/staging/gdm72xx/TODO @@ -0,0 +1,5 @@ +TODO: +- Replace kernel_thread with kthread in gdm_usb.c +- Replace hard-coded firmware paths with request_firmware in + sdio_boot.c and usb_boot.c +- Clean up coding style to meet kernel standard. diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c new file mode 100644 index 0000000..0217680 --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -0,0 +1,460 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/version.h> +#include <linux/etherdevice.h> +#include <asm/byteorder.h> + +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/if_ether.h> + +#include "gdm_wimax.h" +#include "hci.h" +#include "gdm_qos.h" + +#define B2H(x) __be16_to_cpu(x) + +#undef dprintk +#define dprintk(fmt, args ...) printk(KERN_DEBUG "[QoS] " fmt, ## args) +#undef wprintk +#define wprintk(fmt, args ...) \ + printk(KERN_WARNING "[QoS WARNING] " fmt, ## args) +#undef eprintk +#define eprintk(fmt, args ...) printk(KERN_ERR "[QoS ERROR] " fmt, ## args) + + +#define MAX_FREE_LIST_CNT 32 +static struct { + struct list_head head; + int cnt; + spinlock_t lock; +} qos_free_list; + +static void init_qos_entry_list(void) +{ + qos_free_list.cnt = 0; + INIT_LIST_HEAD(&qos_free_list.head); + spin_lock_init(&qos_free_list.lock); +} + +static void *alloc_qos_entry(void) +{ + struct qos_entry_s *entry; + unsigned long flags; + + spin_lock_irqsave(&qos_free_list.lock, flags); + if (qos_free_list.cnt) { + entry = list_entry(qos_free_list.head.prev, struct qos_entry_s, + list); + list_del(&entry->list); + qos_free_list.cnt--; + spin_unlock_irqrestore(&qos_free_list.lock, flags); + return entry; + } + spin_unlock_irqrestore(&qos_free_list.lock, flags); + + entry = kmalloc(sizeof(struct qos_entry_s), GFP_ATOMIC); + return entry; +} + +static void free_qos_entry(void *entry) +{ + struct qos_entry_s *qentry = (struct qos_entry_s *) entry; + unsigned long flags; + + spin_lock_irqsave(&qos_free_list.lock, flags); + if (qos_free_list.cnt < MAX_FREE_LIST_CNT) { + list_add(&qentry->list, &qos_free_list.head); + qos_free_list.cnt++; + spin_unlock_irqrestore(&qos_free_list.lock, flags); + return; + } + spin_unlock_irqrestore(&qos_free_list.lock, flags); + + kfree(entry); +} + +static void free_qos_entry_list(struct list_head *free_list) +{ + struct qos_entry_s *entry, *n; + int total_free = 0; + + list_for_each_entry_safe(entry, n, free_list, list) { + list_del(&entry->list); + kfree(entry); + total_free++; + } + + dprintk("%s: total_free_cnt=%d\n", __func__, total_free); +} + +void gdm_qos_init(void *nic_ptr) +{ + struct nic *nic = nic_ptr; + struct qos_cb_s *qcb = &nic->qos; + int i; + + for (i = 0 ; i < QOS_MAX; i++) { + INIT_LIST_HEAD(&qcb->qos_list[i]); + qcb->csr[i].QoSBufCount = 0; + qcb->csr[i].Enabled = 0; + } + + qcb->qos_list_cnt = 0; + qcb->qos_null_idx = QOS_MAX-1; + qcb->qos_limit_size = 255; + + spin_lock_init(&qcb->qos_lock); + + init_qos_entry_list(); +} + +void gdm_qos_release_list(void *nic_ptr) +{ + struct nic *nic = nic_ptr; + struct qos_cb_s *qcb = &nic->qos; + unsigned long flags; + struct qos_entry_s *entry, *n; + struct list_head free_list; + int i; + + INIT_LIST_HEAD(&free_list); + + spin_lock_irqsave(&qcb->qos_lock, flags); + + for (i = 0; i < QOS_MAX; i++) { + qcb->csr[i].QoSBufCount = 0; + qcb->csr[i].Enabled = 0; + } + + qcb->qos_list_cnt = 0; + qcb->qos_null_idx = QOS_MAX-1; + + for (i = 0; i < QOS_MAX; i++) { + list_for_each_entry_safe(entry, n, &qcb->qos_list[i], list) { + list_move_tail(&entry->list, &free_list); + } + } + spin_unlock_irqrestore(&qcb->qos_lock, flags); + free_qos_entry_list(&free_list); +} + +static u32 chk_ipv4_rule(struct gdm_wimax_csr_s *csr, u8 *Stream, u8 *port) +{ + int i; + + if (csr->ClassifierRuleEnable&IPTYPEOFSERVICE) { + if (((Stream[1] & csr->IPToSMask) < csr->IPToSLow) || + ((Stream[1] & csr->IPToSMask) > csr->IPToSHigh)) + return 1; + } + + if (csr->ClassifierRuleEnable&PROTOCOL) { + if (Stream[9] != csr->Protocol) + return 1; + } + + if (csr->ClassifierRuleEnable&IPMASKEDSRCADDRESS) { + for (i = 0; i < 4; i++) { + if ((Stream[12 + i] & csr->IPSrcAddrMask[i]) != + (csr->IPSrcAddr[i] & csr->IPSrcAddrMask[i])) + return 1; + } + } + + if (csr->ClassifierRuleEnable&IPMASKEDDSTADDRESS) { + for (i = 0; i < 4; i++) { + if ((Stream[16 + i] & csr->IPDstAddrMask[i]) != + (csr->IPDstAddr[i] & csr->IPDstAddrMask[i])) + return 1; + } + } + + if (csr->ClassifierRuleEnable&PROTOCOLSRCPORTRANGE) { + i = ((port[0]<<8)&0xff00)+port[1]; + if ((i < csr->SrcPortLow) || (i > csr->SrcPortHigh)) + return 1; + } + + if (csr->ClassifierRuleEnable&PROTOCOLDSTPORTRANGE) { + i = ((port[2]<<8)&0xff00)+port[3]; + if ((i < csr->DstPortLow) || (i > csr->DstPortHigh)) + return 1; + } + + return 0; +} + +static u32 get_qos_index(struct nic *nic, u8* iph, u8* tcpudph) +{ + u32 IP_Ver, Header_Len, i; + struct qos_cb_s *qcb = &nic->qos; + + if (iph == NULL || tcpudph == NULL) + return -1; + + IP_Ver = (iph[0]>>4)&0xf; + Header_Len = iph[0]&0xf; + + if (IP_Ver == 4) { + for (i = 0; i < QOS_MAX; i++) { + if (qcb->csr[i].Enabled) { + if (qcb->csr[i].ClassifierRuleEnable) { + if (chk_ipv4_rule(&qcb->csr[i], iph, + tcpudph) == 0) + return i; + } + } + } + } + + return -1; +} + +static u32 extract_qos_list(struct nic *nic, struct list_head *head) +{ + struct qos_cb_s *qcb = &nic->qos; + struct qos_entry_s *entry; + int i; + + INIT_LIST_HEAD(head); + + for (i = 0; i < QOS_MAX; i++) { + if (qcb->csr[i].Enabled) { + if (qcb->csr[i].QoSBufCount < qcb->qos_limit_size) { + if (!list_empty(&qcb->qos_list[i])) { + entry = list_entry( + qcb->qos_list[i].prev, + struct qos_entry_s, list); + list_move_tail(&entry->list, head); + qcb->csr[i].QoSBufCount++; + + if (!list_empty(&qcb->qos_list[i])) + wprintk("QoS Index(%d) " + "is piled!!\n", i); + } + } + } + } + + return 0; +} + +static void send_qos_list(struct nic *nic, struct list_head *head) +{ + struct qos_entry_s *entry, *n; + + list_for_each_entry_safe(entry, n, head, list) { + list_del(&entry->list); + free_qos_entry(entry); + gdm_wimax_send_tx(entry->skb, entry->dev); + } +} + +int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + int index; + struct qos_cb_s *qcb = &nic->qos; + unsigned long flags; + struct ethhdr *ethh = (struct ethhdr *) (skb->data + HCI_HEADER_SIZE); + struct iphdr *iph = (struct iphdr *) ((char *) ethh + ETH_HLEN); + struct tcphdr *tcph; + struct qos_entry_s *entry = NULL; + struct list_head send_list; + int ret = 0; + + tcph = (struct tcphdr *) iph + iph->ihl*4; + + if (B2H(ethh->h_proto) == ETH_P_IP) { + if (qcb->qos_list_cnt && !qos_free_list.cnt) { + entry = alloc_qos_entry(); + entry->skb = skb; + entry->dev = dev; + dprintk("qcb->qos_list_cnt=%d\n", qcb->qos_list_cnt); + } + + spin_lock_irqsave(&qcb->qos_lock, flags); + if (qcb->qos_list_cnt) { + index = get_qos_index(nic, (u8 *)iph, (u8 *) tcph); + if (index == -1) + index = qcb->qos_null_idx; + + if (!entry) { + entry = alloc_qos_entry(); + entry->skb = skb; + entry->dev = dev; + } + + list_add_tail(&entry->list, &qcb->qos_list[index]); + extract_qos_list(nic, &send_list); + spin_unlock_irqrestore(&qcb->qos_lock, flags); + send_qos_list(nic, &send_list); + goto out; + } + spin_unlock_irqrestore(&qcb->qos_lock, flags); + if (entry) + free_qos_entry(entry); + } + + ret = gdm_wimax_send_tx(skb, dev); +out: + return ret; +} + +static u32 get_csr(struct qos_cb_s *qcb, u32 SFID, int mode) +{ + int i; + + for (i = 0; i < qcb->qos_list_cnt; i++) { + if (qcb->csr[i].SFID == SFID) + return i; + } + + if (mode) { + for (i = 0; i < QOS_MAX; i++) { + if (qcb->csr[i].Enabled == 0) { + qcb->csr[i].Enabled = 1; + qcb->qos_list_cnt++; + return i; + } + } + } + return -1; +} + +#define QOS_CHANGE_DEL 0xFC +#define QOS_ADD 0xFD +#define QOS_REPORT 0xFE + +void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) +{ + struct nic *nic = nic_ptr; + u32 i, SFID, index, pos; + u8 subCmdEvt; + u8 len; + struct qos_cb_s *qcb = &nic->qos; + struct qos_entry_s *entry, *n; + struct list_head send_list; + struct list_head free_list; + unsigned long flags; + + subCmdEvt = (u8)buf[4]; + + if (subCmdEvt == QOS_REPORT) { + len = (u8)buf[5]; + + spin_lock_irqsave(&qcb->qos_lock, flags); + for (i = 0; i < qcb->qos_list_cnt; i++) { + SFID = ((buf[(i*5)+6]<<24)&0xff000000); + SFID += ((buf[(i*5)+7]<<16)&0xff0000); + SFID += ((buf[(i*5)+8]<<8)&0xff00); + SFID += (buf[(i*5)+9]); + index = get_csr(qcb, SFID, 0); + if (index == -1) { + spin_unlock_irqrestore(&qcb->qos_lock, flags); + eprintk("QoS ERROR: No SF\n"); + return; + } + qcb->csr[index].QoSBufCount = buf[(i*5)+10]; + } + + extract_qos_list(nic, &send_list); + spin_unlock_irqrestore(&qcb->qos_lock, flags); + send_qos_list(nic, &send_list); + return; + } else if (subCmdEvt == QOS_ADD) { + pos = 5; + len = (u8)buf[pos++]; + + SFID = ((buf[pos++]<<24)&0xff000000); + SFID += ((buf[pos++]<<16)&0xff0000); + SFID += ((buf[pos++]<<8)&0xff00); + SFID += (buf[pos++]); + + index = get_csr(qcb, SFID, 1); + if (index == -1) { + eprintk("QoS ERROR: csr Update Error\n"); + return; + } + + dprintk("QOS_ADD SFID = 0x%x, index=%d\n", SFID, index); + + spin_lock_irqsave(&qcb->qos_lock, flags); + qcb->csr[index].SFID = SFID; + qcb->csr[index].ClassifierRuleEnable = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].ClassifierRuleEnable += buf[pos++]; + if (qcb->csr[index].ClassifierRuleEnable == 0) + qcb->qos_null_idx = index; + qcb->csr[index].IPToSMask = buf[pos++]; + qcb->csr[index].IPToSLow = buf[pos++]; + qcb->csr[index].IPToSHigh = buf[pos++]; + qcb->csr[index].Protocol = buf[pos++]; + qcb->csr[index].IPSrcAddrMask[0] = buf[pos++]; + qcb->csr[index].IPSrcAddrMask[1] = buf[pos++]; + qcb->csr[index].IPSrcAddrMask[2] = buf[pos++]; + qcb->csr[index].IPSrcAddrMask[3] = buf[pos++]; + qcb->csr[index].IPSrcAddr[0] = buf[pos++]; + qcb->csr[index].IPSrcAddr[1] = buf[pos++]; + qcb->csr[index].IPSrcAddr[2] = buf[pos++]; + qcb->csr[index].IPSrcAddr[3] = buf[pos++]; + qcb->csr[index].IPDstAddrMask[0] = buf[pos++]; + qcb->csr[index].IPDstAddrMask[1] = buf[pos++]; + qcb->csr[index].IPDstAddrMask[2] = buf[pos++]; + qcb->csr[index].IPDstAddrMask[3] = buf[pos++]; + qcb->csr[index].IPDstAddr[0] = buf[pos++]; + qcb->csr[index].IPDstAddr[1] = buf[pos++]; + qcb->csr[index].IPDstAddr[2] = buf[pos++]; + qcb->csr[index].IPDstAddr[3] = buf[pos++]; + qcb->csr[index].SrcPortLow = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].SrcPortLow += buf[pos++]; + qcb->csr[index].SrcPortHigh = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].SrcPortHigh += buf[pos++]; + qcb->csr[index].DstPortLow = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].DstPortLow += buf[pos++]; + qcb->csr[index].DstPortHigh = ((buf[pos++]<<8)&0xff00); + qcb->csr[index].DstPortHigh += buf[pos++]; + + qcb->qos_limit_size = 254/qcb->qos_list_cnt; + spin_unlock_irqrestore(&qcb->qos_lock, flags); + } else if (subCmdEvt == QOS_CHANGE_DEL) { + pos = 5; + len = (u8)buf[pos++]; + SFID = ((buf[pos++]<<24)&0xff000000); + SFID += ((buf[pos++]<<16)&0xff0000); + SFID += ((buf[pos++]<<8)&0xff00); + SFID += (buf[pos++]); + index = get_csr(qcb, SFID, 1); + if (index == -1) { + eprintk("QoS ERROR: Wrong index(%d)\n", index); + return; + } + + dprintk("QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", SFID, index); + + INIT_LIST_HEAD(&free_list); + + spin_lock_irqsave(&qcb->qos_lock, flags); + qcb->csr[index].Enabled = 0; + qcb->qos_list_cnt--; + qcb->qos_limit_size = 254/qcb->qos_list_cnt; + + list_for_each_entry_safe(entry, n, &qcb->qos_list[index], + list) { + list_move_tail(&entry->list, &free_list); + } + spin_unlock_irqrestore(&qcb->qos_lock, flags); + free_qos_entry_list(&free_list); + } +} diff --git a/drivers/staging/gdm72xx/gdm_qos.h b/drivers/staging/gdm72xx/gdm_qos.h new file mode 100644 index 0000000..33f2bd4 --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_qos.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if !defined(GDM_QOS_H_20090403) +#define GDM_QOS_H_20090403 + +#include <linux/types.h> +#include <linux/usb.h> +#include <linux/list.h> + +#define BOOLEAN u8 + +#define QOS_MAX 16 +#define IPTYPEOFSERVICE 0x8000 +#define PROTOCOL 0x4000 +#define IPMASKEDSRCADDRESS 0x2000 +#define IPMASKEDDSTADDRESS 0x1000 +#define PROTOCOLSRCPORTRANGE 0x800 +#define PROTOCOLDSTPORTRANGE 0x400 +#define DSTMACADDR 0x200 +#define SRCMACADDR 0x100 +#define ETHERTYPE 0x80 +#define IEEE802_1DUSERPRIORITY 0x40 +#define IEEE802_1QVLANID 0x10 + +struct gdm_wimax_csr_s { + /* union{ + U16 all; + struct _CS_CLASSIFIER_RULE_ENABLE{ + IPTypeOfService:1, + Protocol:1, + IPMaskedSrcAddress:1, + IPMaskedDstAddress:1, + ProtocolSrcPortRange:1, + ProtocolDstPortRange:1, + DstMacAddr:1, + SrcMacAddr:1, + Ethertype:1, + IEEE802_1DUserPriority:1, + IEEE802_1QVLANID:1, + Reserved:5; + } fields; + } */ + BOOLEAN Enabled; + u32 SFID; + u8 QoSBufCount; + u16 ClassifierRuleEnable; + u8 IPToSLow; + u8 IPToSHigh; + u8 IPToSMask; + u8 Protocol; + u8 IPSrcAddr[16]; + u8 IPSrcAddrMask[16]; + u8 IPDstAddr[16]; + u8 IPDstAddrMask[16]; + u16 SrcPortLow; + u16 SrcPortHigh; + u16 DstPortLow; + u16 DstPortHigh; +}; + +struct qos_entry_s { + struct list_head list; + struct sk_buff *skb; + struct net_device *dev; + +}; + +struct qos_cb_s { + struct list_head qos_list[QOS_MAX]; + u32 qos_list_cnt; + u32 qos_null_idx; + struct gdm_wimax_csr_s csr[QOS_MAX]; + spinlock_t qos_lock; + u32 qos_limit_size; +}; + +void gdm_qos_init(void *nic_ptr); +void gdm_qos_release_list(void *nic_ptr); +int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev); +void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size); + +#endif diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c new file mode 100644 index 0000000..e1a3dd2 --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/version.h> + +#include <linux/mmc/core.h> +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_func.h> +#include <linux/mmc/sdio_ids.h> + +#include "gdm_sdio.h" +#include "gdm_wimax.h" +#include "sdio_boot.h" +#include "hci.h" + +#define TYPE_A_HEADER_SIZE 4 +#define TYPE_A_LOOKAHEAD_SIZE 16 + +#define MAX_NR_RX_BUF 4 + +#define SDU_TX_BUF_SIZE 2048 +#define TX_BUF_SIZE 2048 +#define TX_CHUNK_SIZE (2048 - TYPE_A_HEADER_SIZE) +#define RX_BUF_SIZE (25*1024) + +#define TX_HZ 2000 +#define TX_INTERVAL (1000000/TX_HZ) + +/*#define DEBUG*/ + +static int init_sdio(struct sdiowm_dev *sdev); +static void release_sdio(struct sdiowm_dev *sdev); + +#ifdef DEBUG +static void hexdump(char *title, u8 *data, int len) +{ + int i; + + printk(KERN_DEBUG "%s: length = %d\n", title, len); + for (i = 0; i < len; i++) { + printk(KERN_DEBUG "%02x ", data[i]); + if ((i & 0xf) == 0xf) + printk(KERN_DEBUG "\n"); + } + printk(KERN_DEBUG "\n"); +} +#endif + +static struct sdio_tx *alloc_tx_struct(struct tx_cxt *tx) +{ + struct sdio_tx *t = NULL; + + t = kmalloc(sizeof(*t), GFP_ATOMIC); + if (t == NULL) + goto out; + + memset(t, 0, sizeof(*t)); + + t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); + if (t->buf == NULL) + goto out; + + t->tx_cxt = tx; + + return t; +out: + if (t) { + kfree(t->buf); + kfree(t); + } + return NULL; +} + +static void free_tx_struct(struct sdio_tx *t) +{ + if (t) { + kfree(t->buf); + kfree(t); + } +} + +static struct sdio_rx *alloc_rx_struct(struct rx_cxt *rx) +{ + struct sdio_rx *r = NULL; + + r = kmalloc(sizeof(*r), GFP_ATOMIC); + if (r == NULL) + goto out; + + memset(r, 0, sizeof(*r)); + + r->rx_cxt = rx; + + return r; +out: + kfree(r); + return NULL; +} + +static void free_rx_struct(struct sdio_rx *r) +{ + kfree(r); +} + +/* Before this function is called, spin lock should be locked. */ +static struct sdio_tx *get_tx_struct(struct tx_cxt *tx, int *no_spc) +{ + struct sdio_tx *t; + + if (list_empty(&tx->free_list)) + return NULL; + + t = list_entry(tx->free_list.prev, struct sdio_tx, list); + list_del(&t->list); + + *no_spc = list_empty(&tx->free_list) ? 1 : 0; + + return t; +} + +/* Before this function is called, spin lock should be locked. */ +static void put_tx_struct(struct tx_cxt *tx, struct sdio_tx *t) +{ + list_add_tail(&t->list, &tx->free_list); +} + +/* Before this function is called, spin lock should be locked. */ +static struct sdio_rx *get_rx_struct(struct rx_cxt *rx) +{ + struct sdio_rx *r; + + if (list_empty(&rx->free_list)) + return NULL; + + r = list_entry(rx->free_list.prev, struct sdio_rx, list); + list_del(&r->list); + + return r; +} + +/* Before this function is called, spin lock should be locked. */ +static void put_rx_struct(struct rx_cxt *rx, struct sdio_rx *r) +{ + list_add_tail(&r->list, &rx->free_list); +} + +static int init_sdio(struct sdiowm_dev *sdev) +{ + int ret = 0, i; + struct tx_cxt *tx = &sdev->tx; + struct rx_cxt *rx = &sdev->rx; + struct sdio_tx *t; + struct sdio_rx *r; + + INIT_LIST_HEAD(&tx->free_list); + INIT_LIST_HEAD(&tx->sdu_list); + INIT_LIST_HEAD(&tx->hci_list); + + spin_lock_init(&tx->lock); + + tx->sdu_buf = kmalloc(SDU_TX_BUF_SIZE, GFP_KERNEL); + if (tx->sdu_buf == NULL) { + printk(KERN_ERR "Failed to allocate SDU tx buffer.\n"); + goto fail; + } + + for (i = 0; i < MAX_NR_SDU_BUF; i++) { + t = alloc_tx_struct(tx); + if (t == NULL) { + ret = -ENOMEM; + goto fail; + } + list_add(&t->list, &tx->free_list); + } + + INIT_LIST_HEAD(&rx->free_list); + INIT_LIST_HEAD(&rx->req_list); + + spin_lock_init(&rx->lock); + + for (i = 0; i < MAX_NR_RX_BUF; i++) { + r = alloc_rx_struct(rx); + if (r == NULL) { + ret = -ENOMEM; + goto fail; + } + list_add(&r->list, &rx->free_list); + } + + rx->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); + if (rx->rx_buf == NULL) { + printk(KERN_ERR "Failed to allocate rx buffer.\n"); + goto fail; + } + + return 0; + +fail: + release_sdio(sdev); + return ret; +} + +static void release_sdio(struct sdiowm_dev *sdev) +{ + struct tx_cxt *tx = &sdev->tx; + struct rx_cxt *rx = &sdev->rx; + struct sdio_tx *t, *t_next; + struct sdio_rx *r, *r_next; + + kfree(tx->sdu_buf); + + list_for_each_entry_safe(t, t_next, &tx->free_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + list_for_each_entry_safe(t, t_next, &tx->hci_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + kfree(rx->rx_buf); + + list_for_each_entry_safe(r, r_next, &rx->free_list, list) { + list_del(&r->list); + free_rx_struct(r); + } + + list_for_each_entry_safe(r, r_next, &rx->req_list, list) { + list_del(&r->list); + free_rx_struct(r); + } +} + +static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len) +{ + int n, blocks, ret, remain; + + sdio_claim_host(func); + + blocks = len / func->cur_blksize; + n = blocks * func->cur_blksize; + if (blocks) { + ret = sdio_memcpy_toio(func, 0, data, n); + if (ret < 0) { + if (ret != -ENOMEDIUM) + printk(KERN_ERR "gdmwms: %s error: ret = %d\n", + __func__, ret); + goto end_io; + } + } + + remain = len - n; + remain = (remain + 3) & ~3; + + if (remain) { + ret = sdio_memcpy_toio(func, 0, data + n, remain); + if (ret < 0) { + if (ret != -ENOMEDIUM) + printk(KERN_ERR "gdmwms: %s error: ret = %d\n", + __func__, ret); + goto end_io; + } + } + +end_io: + sdio_release_host(func); +} + +static void send_sdu(struct sdio_func *func, struct tx_cxt *tx) +{ + struct list_head *l, *next; + struct hci_s *hci; + struct sdio_tx *t; + int pos, len, i, estlen, aggr_num = 0, aggr_len; + u8 *buf; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + + pos = TYPE_A_HEADER_SIZE + HCI_HEADER_SIZE; + list_for_each_entry(t, &tx->sdu_list, list) { + estlen = ((t->len + 3) & ~3) + 4; + if ((pos + estlen) > SDU_TX_BUF_SIZE) + break; + + aggr_num++; + memcpy(tx->sdu_buf + pos, t->buf, t->len); + memset(tx->sdu_buf + pos + t->len, 0, estlen - t->len); + pos += estlen; + } + aggr_len = pos; + + hci = (struct hci_s *)(tx->sdu_buf + TYPE_A_HEADER_SIZE); + hci->cmd_evt = H2B(WIMAX_TX_SDU_AGGR); + hci->length = H2B(aggr_len - TYPE_A_HEADER_SIZE - HCI_HEADER_SIZE); + + spin_unlock_irqrestore(&tx->lock, flags); + +#ifdef DEBUG + hexdump("sdio_send", tx->sdu_buf + TYPE_A_HEADER_SIZE, + aggr_len - TYPE_A_HEADER_SIZE); +#endif + + for (pos = TYPE_A_HEADER_SIZE; pos < aggr_len; pos += TX_CHUNK_SIZE) { + len = aggr_len - pos; + len = len > TX_CHUNK_SIZE ? TX_CHUNK_SIZE : len; + buf = tx->sdu_buf + pos - TYPE_A_HEADER_SIZE; + + buf[0] = len & 0xff; + buf[1] = (len >> 8) & 0xff; + buf[2] = (len >> 16) & 0xff; + buf[3] = (pos + len) >= aggr_len ? 0 : 1; + send_sdio_pkt(func, buf, len + TYPE_A_HEADER_SIZE); + } + + spin_lock_irqsave(&tx->lock, flags); + + for (l = tx->sdu_list.next, i = 0; i < aggr_num; i++, l = next) { + next = l->next; + t = list_entry(l, struct sdio_tx, list); + if (t->callback) + t->callback(t->cb_data); + + list_del(l); + put_tx_struct(t->tx_cxt, t); + } + + do_gettimeofday(&tx->sdu_stamp); + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void send_hci(struct sdio_func *func, struct tx_cxt *tx, + struct sdio_tx *t) +{ + unsigned long flags; + +#ifdef DEBUG + hexdump("sdio_send", t->buf + TYPE_A_HEADER_SIZE, + t->len - TYPE_A_HEADER_SIZE); +#endif + send_sdio_pkt(func, t->buf, t->len); + + spin_lock_irqsave(&tx->lock, flags); + if (t->callback) + t->callback(t->cb_data); + free_tx_struct(t); + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void do_tx(struct work_struct *work) +{ + struct sdiowm_dev *sdev = container_of(work, struct sdiowm_dev, ws); + struct sdio_func *func = sdev->func; + struct tx_cxt *tx = &sdev->tx; + struct sdio_tx *t = NULL; + struct timeval now, *before; + int is_sdu = 0; + long diff; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + if (!tx->can_send) { + spin_unlock_irqrestore(&tx->lock, flags); + return; + } + + if (!list_empty(&tx->hci_list)) { + t = list_entry(tx->hci_list.next, struct sdio_tx, list); + list_del(&t->list); + is_sdu = 0; + } else if (!tx->stop_sdu_tx && !list_empty(&tx->sdu_list)) { + do_gettimeofday(&now); + before = &tx->sdu_stamp; + + diff = (now.tv_sec - before->tv_sec) * 1000000 + + (now.tv_usec - before->tv_usec); + if (diff >= 0 && diff < TX_INTERVAL) { + schedule_work(&sdev->ws); + spin_unlock_irqrestore(&tx->lock, flags); + return; + } + is_sdu = 1; + } + + if (!is_sdu && t == NULL) { + spin_unlock_irqrestore(&tx->lock, flags); + return; + } + + tx->can_send = 0; + + spin_unlock_irqrestore(&tx->lock, flags); + + if (is_sdu) + send_sdu(func, tx); + else + send_hci(func, tx, t); +} + +static int gdm_sdio_send(void *priv_dev, void *data, int len, + void (*cb)(void *data), void *cb_data) +{ + struct sdiowm_dev *sdev = priv_dev; + struct tx_cxt *tx = &sdev->tx; + struct sdio_tx *t; + u8 *pkt = data; + int no_spc = 0; + u16 cmd_evt; + unsigned long flags; + + BUG_ON(len > TX_BUF_SIZE - TYPE_A_HEADER_SIZE); + + spin_lock_irqsave(&tx->lock, flags); + + cmd_evt = (pkt[0] << 8) | pkt[1]; + if (cmd_evt == WIMAX_TX_SDU) { + t = get_tx_struct(tx, &no_spc); + if (t == NULL) { + /* This case must not happen. */ + spin_unlock_irqrestore(&tx->lock, flags); + return -ENOSPC; + } + list_add_tail(&t->list, &tx->sdu_list); + + memcpy(t->buf, data, len); + + t->len = len; + t->callback = cb; + t->cb_data = cb_data; + } else { + t = alloc_tx_struct(tx); + if (t == NULL) { + spin_unlock_irqrestore(&tx->lock, flags); + return -ENOMEM; + } + list_add_tail(&t->list, &tx->hci_list); + + t->buf[0] = len & 0xff; + t->buf[1] = (len >> 8) & 0xff; + t->buf[2] = (len >> 16) & 0xff; + t->buf[3] = 2; + memcpy(t->buf + TYPE_A_HEADER_SIZE, data, len); + + t->len = len + TYPE_A_HEADER_SIZE; + t->callback = cb; + t->cb_data = cb_data; + } + + if (tx->can_send) + schedule_work(&sdev->ws); + + spin_unlock_irqrestore(&tx->lock, flags); + + if (no_spc) + return -ENOSPC; + + return 0; +} + +/* + * Handle the HCI, WIMAX_SDU_TX_FLOW. + */ +static int control_sdu_tx_flow(struct sdiowm_dev *sdev, u8 *hci_data, int len) +{ + struct tx_cxt *tx = &sdev->tx; + u16 cmd_evt; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + + cmd_evt = (hci_data[0] << 8) | (hci_data[1]); + if (cmd_evt != WIMAX_SDU_TX_FLOW) + goto out; + + if (hci_data[4] == 0) { +#ifdef DEBUG + printk(KERN_DEBUG "WIMAX ==> STOP SDU TX\n"); +#endif + tx->stop_sdu_tx = 1; + } else if (hci_data[4] == 1) { +#ifdef DEBUG + printk(KERN_DEBUG "WIMAX ==> START SDU TX\n"); +#endif + tx->stop_sdu_tx = 0; + if (tx->can_send) + schedule_work(&sdev->ws); + /* + * If free buffer for sdu tx doesn't exist, then tx queue + * should not be woken. For this reason, don't pass the command, + * START_SDU_TX. + */ + if (list_empty(&tx->free_list)) + len = 0; + } + +out: + spin_unlock_irqrestore(&tx->lock, flags); + return len; +} + +static void gdm_sdio_irq(struct sdio_func *func) +{ + struct phy_dev *phy_dev = sdio_get_drvdata(func); + struct sdiowm_dev *sdev = phy_dev->priv_dev; + struct tx_cxt *tx = &sdev->tx; + struct rx_cxt *rx = &sdev->rx; + struct sdio_rx *r; + unsigned long flags; + u8 val, hdr[TYPE_A_LOOKAHEAD_SIZE], *buf; + u32 len, blocks, n; + int ret, remain; + + /* Check interrupt */ + val = sdio_readb(func, 0x13, &ret); + if (val & 0x01) + sdio_writeb(func, 0x01, 0x13, &ret); /* clear interrupt */ + else + return; + + ret = sdio_memcpy_fromio(func, hdr, 0x0, TYPE_A_LOOKAHEAD_SIZE); + if (ret) { + printk(KERN_ERR "Cannot read from function %d\n", func->num); + goto done; + } + + len = (hdr[2] << 16) | (hdr[1] << 8) | hdr[0]; + if (len > (RX_BUF_SIZE - TYPE_A_HEADER_SIZE)) { + printk(KERN_ERR "Too big Type-A size: %d\n", len); + goto done; + } + + if (hdr[3] == 1) { /* Ack */ +#ifdef DEBUG + u32 *ack_seq = (u32 *)&hdr[4]; +#endif + spin_lock_irqsave(&tx->lock, flags); + tx->can_send = 1; + + if (!list_empty(&tx->sdu_list) || !list_empty(&tx->hci_list)) + schedule_work(&sdev->ws); + spin_unlock_irqrestore(&tx->lock, flags); +#ifdef DEBUG + printk(KERN_DEBUG "Ack... %0x\n", ntohl(*ack_seq)); +#endif + goto done; + } + + memcpy(rx->rx_buf, hdr + TYPE_A_HEADER_SIZE, + TYPE_A_LOOKAHEAD_SIZE - TYPE_A_HEADER_SIZE); + + buf = rx->rx_buf + TYPE_A_LOOKAHEAD_SIZE - TYPE_A_HEADER_SIZE; + remain = len - TYPE_A_LOOKAHEAD_SIZE + TYPE_A_HEADER_SIZE; + if (remain <= 0) + goto end_io; + + blocks = remain / func->cur_blksize; + + if (blocks) { + n = blocks * func->cur_blksize; + ret = sdio_memcpy_fromio(func, buf, 0x0, n); + if (ret) { + printk(KERN_ERR "Cannot read from function %d\n", + func->num); + goto done; + } + buf += n; + remain -= n; + } + + if (remain) { + ret = sdio_memcpy_fromio(func, buf, 0x0, remain); + if (ret) { + printk(KERN_ERR "Cannot read from function %d\n", + func->num); + goto done; + } + } + +end_io: +#ifdef DEBUG + hexdump("sdio_receive", rx->rx_buf, len); +#endif + len = control_sdu_tx_flow(sdev, rx->rx_buf, len); + + spin_lock_irqsave(&rx->lock, flags); + + if (!list_empty(&rx->req_list)) { + r = list_entry(rx->req_list.next, struct sdio_rx, list); + spin_unlock_irqrestore(&rx->lock, flags); + if (r->callback) + r->callback(r->cb_data, rx->rx_buf, len); + spin_lock_irqsave(&rx->lock, flags); + list_del(&r->list); + put_rx_struct(rx, r); + } + + spin_unlock_irqrestore(&rx->lock, flags); + +done: + sdio_writeb(func, 0x00, 0x10, &ret); /* PCRRT */ + if (!phy_dev->netdev) + register_wimax_device(phy_dev, &func->dev); +} + +static int gdm_sdio_receive(void *priv_dev, + void (*cb)(void *cb_data, void *data, int len), + void *cb_data) +{ + struct sdiowm_dev *sdev = priv_dev; + struct rx_cxt *rx = &sdev->rx; + struct sdio_rx *r; + unsigned long flags; + + spin_lock_irqsave(&rx->lock, flags); + r = get_rx_struct(rx); + if (r == NULL) { + spin_unlock_irqrestore(&rx->lock, flags); + return -ENOMEM; + } + + r->callback = cb; + r->cb_data = cb_data; + + list_add_tail(&r->list, &rx->req_list); + spin_unlock_irqrestore(&rx->lock, flags); + + return 0; +} + +static int sdio_wimax_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int ret; + struct phy_dev *phy_dev = NULL; + struct sdiowm_dev *sdev = NULL; + + printk(KERN_INFO "Found GDM SDIO VID = 0x%04x PID = 0x%04x...\n", + func->vendor, func->device); + printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION); + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_claim_irq(func, gdm_sdio_irq); + + ret = sdio_boot(func); + if (ret) + return ret; + + phy_dev = kmalloc(sizeof(*phy_dev), GFP_KERNEL); + if (phy_dev == NULL) { + ret = -ENOMEM; + goto out; + } + sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); + if (sdev == NULL) { + ret = -ENOMEM; + goto out; + } + + memset(phy_dev, 0, sizeof(*phy_dev)); + memset(sdev, 0, sizeof(*sdev)); + + phy_dev->priv_dev = (void *)sdev; + phy_dev->send_func = gdm_sdio_send; + phy_dev->rcv_func = gdm_sdio_receive; + + ret = init_sdio(sdev); + if (sdev < 0) + goto out; + + sdev->func = func; + + sdio_writeb(func, 1, 0x14, &ret); /* Enable interrupt */ + sdio_release_host(func); + + INIT_WORK(&sdev->ws, do_tx); + + sdio_set_drvdata(func, phy_dev); +out: + if (ret) { + kfree(phy_dev); + kfree(sdev); + } + + return ret; +} + +static void sdio_wimax_remove(struct sdio_func *func) +{ + struct phy_dev *phy_dev = sdio_get_drvdata(func); + struct sdiowm_dev *sdev = phy_dev->priv_dev; + + if (phy_dev->netdev) + unregister_wimax_device(phy_dev); + sdio_claim_host(func); + sdio_release_irq(func); + sdio_disable_func(func); + sdio_release_host(func); + release_sdio(sdev); + + kfree(sdev); + kfree(phy_dev); +} + +static const struct sdio_device_id sdio_wimax_ids[] = { + { SDIO_DEVICE(0x0296, 0x5347) }, + {0} +}; + +MODULE_DEVICE_TABLE(sdio, sdio_wimax_ids); + +static struct sdio_driver sdio_wimax_driver = { + .probe = sdio_wimax_probe, + .remove = sdio_wimax_remove, + .name = "sdio_wimax", + .id_table = sdio_wimax_ids, +}; + +static int __init sdio_gdm_wimax_init(void) +{ + return sdio_register_driver(&sdio_wimax_driver); +} + +static void __exit sdio_gdm_wimax_exit(void) +{ + sdio_unregister_driver(&sdio_wimax_driver); +} + +module_init(sdio_gdm_wimax_init); +module_exit(sdio_gdm_wimax_exit); + +MODULE_VERSION(DRIVER_VERSION); +MODULE_DESCRIPTION("GCT WiMax SDIO Device Driver"); +MODULE_AUTHOR("Ethan Park"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm72xx/gdm_sdio.h b/drivers/staging/gdm72xx/gdm_sdio.h new file mode 100644 index 0000000..216e98f --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_sdio.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GDM_SDIO_H__ +#define __GDM_SDIO_H__ + +#include <linux/types.h> +#include <linux/time.h> + +#define MAX_NR_SDU_BUF 64 + +struct sdio_tx { + struct list_head list; + struct tx_cxt *tx_cxt; + + u8 *buf; + int len; + + void (*callback)(void *cb_data); + void *cb_data; +}; + +struct tx_cxt { + struct list_head free_list; + struct list_head sdu_list; + struct list_head hci_list; + struct timeval sdu_stamp; + + u8 *sdu_buf; + + spinlock_t lock; + int can_send; + int stop_sdu_tx; +}; + +struct sdio_rx { + struct list_head list; + struct rx_cxt *rx_cxt; + + void (*callback)(void *cb_data, void *data, int len); + void *cb_data; +}; + +struct rx_cxt { + struct list_head free_list; + struct list_head req_list; + + u8 *rx_buf; + + spinlock_t lock; +}; + +struct sdiowm_dev { + struct sdio_func *func; + + struct tx_cxt tx; + struct rx_cxt rx; + + struct work_struct ws; +}; + +#endif /* __GDM_SDIO_H__ */ diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c new file mode 100644 index 0000000..1e9dc0d --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -0,0 +1,798 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/usb.h> +#include <asm/byteorder.h> + +#include "gdm_usb.h" +#include "gdm_wimax.h" +#include "usb_boot.h" +#include "hci.h" + +#include "usb_ids.h" + +MODULE_DEVICE_TABLE(usb, id_table); + +#define TX_BUF_SIZE 2048 +#if defined(CONFIG_WIMAX_GDM72XX_WIMAX2) +#define RX_BUF_SIZE (128*1024) /* For packet aggregation */ +#else +#define RX_BUF_SIZE 2048 +#endif + +#define GDM7205_PADDING 256 + +#define H2B(x) __cpu_to_be16(x) +#define B2H(x) __be16_to_cpu(x) +#define DB2H(x) __be32_to_cpu(x) + +#define DOWNLOAD_CONF_VALUE 0x21 + +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE + +static DECLARE_WAIT_QUEUE_HEAD(k_wait); +static LIST_HEAD(k_list); +static DEFINE_SPINLOCK(k_lock); +static int k_mode_stop; + +#define K_WAIT_TIME (2 * HZ / 100) + +#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ + +static int init_usb(struct usbwm_dev *udev); +static void release_usb(struct usbwm_dev *udev); + +/*#define DEBUG */ +#ifdef DEBUG +static void hexdump(char *title, u8 *data, int len) +{ + int i; + + printk(KERN_DEBUG "%s: length = %d\n", title, len); + for (i = 0; i < len; i++) { + printk(KERN_DEBUG "%02x ", data[i]); + if ((i & 0xf) == 0xf) + printk(KERN_DEBUG "\n"); + } + printk(KERN_DEBUG "\n"); +} +#endif + +static struct usb_tx *alloc_tx_struct(struct tx_cxt *tx) +{ + struct usb_tx *t = NULL; + + t = kmalloc(sizeof(*t), GFP_ATOMIC); + if (t == NULL) + goto out; + + memset(t, 0, sizeof(*t)); + + t->urb = usb_alloc_urb(0, GFP_ATOMIC); + t->buf = kmalloc(TX_BUF_SIZE, GFP_ATOMIC); + if (t->urb == NULL || t->buf == NULL) + goto out; + + t->tx_cxt = tx; + + return t; +out: + if (t) { + usb_free_urb(t->urb); + kfree(t->buf); + kfree(t); + } + return NULL; +} + +static void free_tx_struct(struct usb_tx *t) +{ + if (t) { + usb_free_urb(t->urb); + kfree(t->buf); + kfree(t); + } +} + +static struct usb_rx *alloc_rx_struct(struct rx_cxt *rx) +{ + struct usb_rx *r = NULL; + + r = kmalloc(sizeof(*r), GFP_ATOMIC); + if (r == NULL) + goto out; + + memset(r, 0, sizeof(*r)); + + r->urb = usb_alloc_urb(0, GFP_ATOMIC); + r->buf = kmalloc(RX_BUF_SIZE, GFP_ATOMIC); + if (r->urb == NULL || r->buf == NULL) + goto out; + + r->rx_cxt = rx; + return r; +out: + if (r) { + usb_free_urb(r->urb); + kfree(r->buf); + kfree(r); + } + return NULL; +} + +static void free_rx_struct(struct usb_rx *r) +{ + if (r) { + usb_free_urb(r->urb); + kfree(r->buf); + kfree(r); + } +} + +/* Before this function is called, spin lock should be locked. */ +static struct usb_tx *get_tx_struct(struct tx_cxt *tx, int *no_spc) +{ + struct usb_tx *t; + + if (list_empty(&tx->free_list)) { + *no_spc = 1; + return NULL; + } + + t = list_entry(tx->free_list.next, struct usb_tx, list); + list_del(&t->list); + + *no_spc = list_empty(&tx->free_list) ? 1 : 0; + + return t; +} + +/* Before this function is called, spin lock should be locked. */ +static void put_tx_struct(struct tx_cxt *tx, struct usb_tx *t) +{ + list_add_tail(&t->list, &tx->free_list); +} + +/* Before this function is called, spin lock should be locked. */ +static struct usb_rx *get_rx_struct(struct rx_cxt *rx) +{ + struct usb_rx *r; + + if (list_empty(&rx->free_list)) { + r = alloc_rx_struct(rx); + if (r == NULL) + return NULL; + + list_add(&r->list, &rx->free_list); + } + + r = list_entry(rx->free_list.next, struct usb_rx, list); + list_del(&r->list); + list_add_tail(&r->list, &rx->used_list); + + return r; +} + +/* Before this function is called, spin lock should be locked. */ +static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r) +{ + list_del(&r->list); + list_add(&r->list, &rx->free_list); +} + +static int init_usb(struct usbwm_dev *udev) +{ + int ret = 0, i; + struct tx_cxt *tx = &udev->tx; + struct rx_cxt *rx = &udev->rx; + struct usb_tx *t; + struct usb_rx *r; + + INIT_LIST_HEAD(&tx->free_list); + INIT_LIST_HEAD(&tx->sdu_list); + INIT_LIST_HEAD(&tx->hci_list); +#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE) + INIT_LIST_HEAD(&tx->pending_list); +#endif + + INIT_LIST_HEAD(&rx->free_list); + INIT_LIST_HEAD(&rx->used_list); + + spin_lock_init(&tx->lock); + spin_lock_init(&rx->lock); + + for (i = 0; i < MAX_NR_SDU_BUF; i++) { + t = alloc_tx_struct(tx); + if (t == NULL) { + ret = -ENOMEM; + goto fail; + } + list_add(&t->list, &tx->free_list); + } + + r = alloc_rx_struct(rx); + if (r == NULL) { + ret = -ENOMEM; + goto fail; + } + + list_add(&r->list, &rx->free_list); + return ret; + +fail: + release_usb(udev); + return ret; +} + +static void release_usb(struct usbwm_dev *udev) +{ + struct tx_cxt *tx = &udev->tx; + struct rx_cxt *rx = &udev->rx; + struct usb_tx *t, *t_next; + struct usb_rx *r, *r_next; + + list_for_each_entry_safe(t, t_next, &tx->sdu_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + list_for_each_entry_safe(t, t_next, &tx->hci_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + list_for_each_entry_safe(t, t_next, &tx->free_list, list) { + list_del(&t->list); + free_tx_struct(t); + } + + list_for_each_entry_safe(r, r_next, &rx->free_list, list) { + list_del(&r->list); + free_rx_struct(r); + } + + list_for_each_entry_safe(r, r_next, &rx->used_list, list) { + list_del(&r->list); + free_rx_struct(r); + } +} + +static void gdm_usb_send_complete(struct urb *urb) +{ + struct usb_tx *t = urb->context; + struct tx_cxt *tx = t->tx_cxt; + u8 *pkt = t->buf; + u16 cmd_evt; + unsigned long flags; + + /* Completion by usb_unlink_urb */ + if (urb->status == -ECONNRESET) + return; + + spin_lock_irqsave(&tx->lock, flags); + + if (t->callback) + t->callback(t->cb_data); + + /* Delete from sdu list or hci list. */ + list_del(&t->list); + + cmd_evt = (pkt[0] << 8) | pkt[1]; + if (cmd_evt == WIMAX_TX_SDU) + put_tx_struct(tx, t); + else + free_tx_struct(t); + + spin_unlock_irqrestore(&tx->lock, flags); +} + +static int gdm_usb_send(void *priv_dev, void *data, int len, + void (*cb)(void *data), void *cb_data) +{ + struct usbwm_dev *udev = priv_dev; + struct usb_device *usbdev = udev->usbdev; + struct tx_cxt *tx = &udev->tx; + struct usb_tx *t; + int padding = udev->padding; + int no_spc = 0, ret; + u8 *pkt = data; + u16 cmd_evt; + unsigned long flags; + + if (!udev->usbdev) { + printk(KERN_ERR "%s: No such device\n", __func__); + return -ENODEV; + } + + BUG_ON(len > TX_BUF_SIZE - padding - 1); + + spin_lock_irqsave(&tx->lock, flags); + + cmd_evt = (pkt[0] << 8) | pkt[1]; + if (cmd_evt == WIMAX_TX_SDU) { + t = get_tx_struct(tx, &no_spc); + if (t == NULL) { + /* This case must not happen. */ + spin_unlock_irqrestore(&tx->lock, flags); + return -ENOSPC; + } + list_add_tail(&t->list, &tx->sdu_list); + } else { + t = alloc_tx_struct(tx); + if (t == NULL) { + spin_unlock_irqrestore(&tx->lock, flags); + return -ENOMEM; + } + list_add_tail(&t->list, &tx->hci_list); + } + + memcpy(t->buf + padding, data, len); + t->callback = cb; + t->cb_data = cb_data; + + /* + * In some cases, USB Module of WiMax is blocked when data size is + * the multiple of 512. So, increment length by one in that case. + */ + if ((len % 512) == 0) + len++; + + usb_fill_bulk_urb(t->urb, + usbdev, + usb_sndbulkpipe(usbdev, 1), + t->buf, + len + padding, + gdm_usb_send_complete, + t); + +#ifdef DEBUG + hexdump("usb_send", t->buf, len + padding); +#endif +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + if (usbdev->state & USB_STATE_SUSPENDED) { + list_add_tail(&t->p_list, &tx->pending_list); + schedule_work(&udev->pm_ws); + goto out; + } +#endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ + +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE + if (udev->bw_switch) { + list_add_tail(&t->p_list, &tx->pending_list); + goto out; + } else if (cmd_evt == WIMAX_SCAN) { + struct rx_cxt *rx; + struct usb_rx *r; + + rx = &udev->rx; + + list_for_each_entry(r, &rx->used_list, list) + usb_unlink_urb(r->urb); + udev->bw_switch = 1; + + spin_lock(&k_lock); + list_add_tail(&udev->list, &k_list); + spin_unlock(&k_lock); + + wake_up(&k_wait); + } +#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ + + ret = usb_submit_urb(t->urb, GFP_ATOMIC); + if (ret) + goto send_fail; + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + usb_mark_last_busy(usbdev); +#endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ + +#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE) +out: +#endif + spin_unlock_irqrestore(&tx->lock, flags); + + if (no_spc) + return -ENOSPC; + + return 0; + +send_fail: + t->callback = NULL; + gdm_usb_send_complete(t->urb); + spin_unlock_irqrestore(&tx->lock, flags); + return ret; +} + +static void gdm_usb_rcv_complete(struct urb *urb) +{ + struct usb_rx *r = urb->context; + struct rx_cxt *rx = r->rx_cxt; + struct usbwm_dev *udev = container_of(r->rx_cxt, struct usbwm_dev, rx); + struct tx_cxt *tx = &udev->tx; + struct usb_tx *t; + u16 cmd_evt; + unsigned long flags; + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + struct usb_device *dev = urb->dev; +#endif + + /* Completion by usb_unlink_urb */ + if (urb->status == -ECONNRESET) + return; + + spin_lock_irqsave(&tx->lock, flags); + + if (!urb->status) { + cmd_evt = (r->buf[0] << 8) | (r->buf[1]); +#ifdef DEBUG + hexdump("usb_receive", r->buf, urb->actual_length); +#endif + if (cmd_evt == WIMAX_SDU_TX_FLOW) { + if (r->buf[4] == 0) { +#ifdef DEBUG + printk(KERN_DEBUG "WIMAX ==> STOP SDU TX\n"); +#endif + list_for_each_entry(t, &tx->sdu_list, list) + usb_unlink_urb(t->urb); + } else if (r->buf[4] == 1) { +#ifdef DEBUG + printk(KERN_DEBUG "WIMAX ==> START SDU TX\n"); +#endif + list_for_each_entry(t, &tx->sdu_list, list) { + usb_submit_urb(t->urb, GFP_ATOMIC); + } + /* + * If free buffer for sdu tx doesn't + * exist, then tx queue should not be + * woken. For this reason, don't pass + * the command, START_SDU_TX. + */ + if (list_empty(&tx->free_list)) + urb->actual_length = 0; + } + } + } + + if (!urb->status && r->callback) + r->callback(r->cb_data, r->buf, urb->actual_length); + + spin_lock(&rx->lock); + put_rx_struct(rx, r); + spin_unlock(&rx->lock); + + spin_unlock_irqrestore(&tx->lock, flags); + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + usb_mark_last_busy(dev); +#endif +} + +static int gdm_usb_receive(void *priv_dev, + void (*cb)(void *cb_data, void *data, int len), + void *cb_data) +{ + struct usbwm_dev *udev = priv_dev; + struct usb_device *usbdev = udev->usbdev; + struct rx_cxt *rx = &udev->rx; + struct usb_rx *r; + unsigned long flags; + + if (!udev->usbdev) { + printk(KERN_ERR "%s: No such device\n", __func__); + return -ENODEV; + } + + spin_lock_irqsave(&rx->lock, flags); + r = get_rx_struct(rx); + spin_unlock_irqrestore(&rx->lock, flags); + + if (r == NULL) + return -ENOMEM; + + r->callback = cb; + r->cb_data = cb_data; + + usb_fill_bulk_urb(r->urb, + usbdev, + usb_rcvbulkpipe(usbdev, 0x82), + r->buf, + RX_BUF_SIZE, + gdm_usb_rcv_complete, + r); + + return usb_submit_urb(r->urb, GFP_ATOMIC); +} + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM +static void do_pm_control(struct work_struct *work) +{ + struct usbwm_dev *udev = container_of(work, struct usbwm_dev, pm_ws); + struct tx_cxt *tx = &udev->tx; + int ret; + unsigned long flags; + + ret = usb_autopm_get_interface(udev->intf); + if (!ret) + usb_autopm_put_interface(udev->intf); + + spin_lock_irqsave(&tx->lock, flags); + if (!(udev->usbdev->state & USB_STATE_SUSPENDED) + && (!list_empty(&tx->hci_list) || !list_empty(&tx->sdu_list))) { + struct usb_tx *t, *temp; + + list_for_each_entry_safe(t, temp, &tx->pending_list, p_list) { + list_del(&t->p_list); + ret = usb_submit_urb(t->urb, GFP_ATOMIC); + + if (ret) { + t->callback = NULL; + gdm_usb_send_complete(t->urb); + } + } + } + spin_unlock_irqrestore(&tx->lock, flags); +} +#endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ + +static int gdm_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int ret = 0; + u8 bConfigurationValue; + struct phy_dev *phy_dev = NULL; + struct usbwm_dev *udev = NULL; + u16 idVendor, idProduct, bcdDevice; + + struct usb_device *usbdev = interface_to_usbdev(intf); + + usb_get_dev(usbdev); + bConfigurationValue = usbdev->actconfig->desc.bConfigurationValue; + + /*USB description is set up with Little-Endian*/ + idVendor = L2H(usbdev->descriptor.idVendor); + idProduct = L2H(usbdev->descriptor.idProduct); + bcdDevice = L2H(usbdev->descriptor.bcdDevice); + + printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n", + idVendor, idProduct); + printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION); + + + if (idProduct == EMERGENCY_PID) { + ret = usb_emergency(usbdev); + goto out; + } + + /* Support for EEPROM bootloader */ + if (bConfigurationValue == DOWNLOAD_CONF_VALUE || + idProduct & B_DOWNLOAD) { + ret = usb_boot(usbdev, bcdDevice); + goto out; + } + + phy_dev = kmalloc(sizeof(*phy_dev), GFP_KERNEL); + if (phy_dev == NULL) { + ret = -ENOMEM; + goto out; + } + udev = kmalloc(sizeof(*udev), GFP_KERNEL); + if (udev == NULL) { + ret = -ENOMEM; + goto out; + } + + memset(phy_dev, 0, sizeof(*phy_dev)); + memset(udev, 0, sizeof(*udev)); + + if (idProduct == 0x7205 || idProduct == 0x7206) + udev->padding = GDM7205_PADDING; + else + udev->padding = 0; + + phy_dev->priv_dev = (void *)udev; + phy_dev->send_func = gdm_usb_send; + phy_dev->rcv_func = gdm_usb_receive; + + ret = init_usb(udev); + if (ret < 0) + goto out; + + udev->usbdev = usbdev; + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + udev->intf = intf; + + intf->needs_remote_wakeup = 1; + device_init_wakeup(&intf->dev, 1); + + pm_runtime_set_autosuspend_delay(&usbdev->dev, 10 * 1000); /* msec */ + + INIT_WORK(&udev->pm_ws, do_pm_control); +#endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ + + ret = register_wimax_device(phy_dev, &intf->dev); + +out: + if (ret) { + kfree(phy_dev); + kfree(udev); + } + usb_set_intfdata(intf, phy_dev); + return ret; +} + +static void gdm_usb_disconnect(struct usb_interface *intf) +{ + u8 bConfigurationValue; + struct phy_dev *phy_dev; + struct usbwm_dev *udev; + u16 idProduct; + struct usb_device *usbdev = interface_to_usbdev(intf); + + bConfigurationValue = usbdev->actconfig->desc.bConfigurationValue; + phy_dev = usb_get_intfdata(intf); + + /*USB description is set up with Little-Endian*/ + idProduct = L2H(usbdev->descriptor.idProduct); + + if (idProduct != EMERGENCY_PID && + bConfigurationValue != DOWNLOAD_CONF_VALUE && + (idProduct & B_DOWNLOAD) == 0) { + udev = phy_dev->priv_dev; + udev->usbdev = NULL; + + unregister_wimax_device(phy_dev); + release_usb(udev); + kfree(udev); + kfree(phy_dev); + } + + usb_put_dev(usbdev); +} + +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM +static int gdm_suspend(struct usb_interface *intf, pm_message_t pm_msg) +{ + struct phy_dev *phy_dev; + struct usbwm_dev *udev; + struct rx_cxt *rx; + struct usb_rx *r; + + phy_dev = usb_get_intfdata(intf); + udev = phy_dev->priv_dev; + rx = &udev->rx; + + list_for_each_entry(r, &rx->used_list, list) + usb_unlink_urb(r->urb); + + return 0; +} + +static int gdm_resume(struct usb_interface *intf) +{ + struct phy_dev *phy_dev; + struct usbwm_dev *udev; + struct rx_cxt *rx; + struct usb_rx *r; + + phy_dev = usb_get_intfdata(intf); + udev = phy_dev->priv_dev; + rx = &udev->rx; + + list_for_each_entry(r, &rx->used_list, list) + usb_submit_urb(r->urb, GFP_ATOMIC); + + return 0; +} + +#endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ + +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE +static int k_mode_thread(void *arg) +{ + struct usbwm_dev *udev; + struct tx_cxt *tx; + struct rx_cxt *rx; + struct usb_tx *t, *temp; + struct usb_rx *r; + unsigned long flags, flags2, expire; + int ret; + + daemonize("k_mode_wimax"); + + while (!k_mode_stop) { + + spin_lock_irqsave(&k_lock, flags2); + while (!list_empty(&k_list)) { + + udev = list_entry(k_list.next, struct usbwm_dev, list); + tx = &udev->tx; + rx = &udev->rx; + + list_del(&udev->list); + spin_unlock_irqrestore(&k_lock, flags2); + + expire = jiffies + K_WAIT_TIME; + while (jiffies < expire) + schedule_timeout(K_WAIT_TIME); + + list_for_each_entry(r, &rx->used_list, list) + usb_submit_urb(r->urb, GFP_ATOMIC); + + spin_lock_irqsave(&tx->lock, flags); + + list_for_each_entry_safe(t, temp, &tx->pending_list, + p_list) { + list_del(&t->p_list); + ret = usb_submit_urb(t->urb, GFP_ATOMIC); + + if (ret) { + t->callback = NULL; + gdm_usb_send_complete(t->urb); + } + } + + udev->bw_switch = 0; + spin_unlock_irqrestore(&tx->lock, flags); + + spin_lock_irqsave(&k_lock, flags2); + } + spin_unlock_irqrestore(&k_lock, flags2); + + interruptible_sleep_on(&k_wait); + } + return 0; +} +#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ + +static struct usb_driver gdm_usb_driver = { + .name = "gdm_wimax", + .probe = gdm_usb_probe, + .disconnect = gdm_usb_disconnect, + .id_table = id_table, +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + .supports_autosuspend = 1, + .suspend = gdm_suspend, + .resume = gdm_resume, + .reset_resume = gdm_resume, +#endif +}; + +static int __init usb_gdm_wimax_init(void) +{ +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE + kernel_thread(k_mode_thread, NULL, CLONE_KERNEL); +#endif /* CONFIG_WIMAX_GDM72XX_K_MODE */ + return usb_register(&gdm_usb_driver); +} + +static void __exit usb_gdm_wimax_exit(void) +{ +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE + k_mode_stop = 1; + wake_up(&k_wait); +#endif + usb_deregister(&gdm_usb_driver); +} + +module_init(usb_gdm_wimax_init); +module_exit(usb_gdm_wimax_exit); + +MODULE_VERSION(DRIVER_VERSION); +MODULE_DESCRIPTION("GCT WiMax Device Driver"); +MODULE_AUTHOR("Ethan Park"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gdm72xx/gdm_usb.h b/drivers/staging/gdm72xx/gdm_usb.h new file mode 100644 index 0000000..ecb891f --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_usb.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GDM_USB_H__ +#define __GDM_USB_H__ + +#include <linux/types.h> +#include <linux/usb.h> +#include <linux/list.h> + +#define B_DIFF_DL_DRV (1<<4) +#define B_DOWNLOAD (1 << 5) +#define MAX_NR_SDU_BUF 64 + +struct usb_tx { + struct list_head list; +#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE) + struct list_head p_list; +#endif + struct tx_cxt *tx_cxt; + + struct urb *urb; + u8 *buf; + + void (*callback)(void *cb_data); + void *cb_data; +}; + +struct tx_cxt { + struct list_head free_list; + struct list_head sdu_list; + struct list_head hci_list; +#if defined(CONFIG_WIMAX_GDM72XX_USB_PM) || defined(CONFIG_WIMAX_GDM72XX_K_MODE) + struct list_head pending_list; +#endif + + spinlock_t lock; +}; + +struct usb_rx { + struct list_head list; + struct rx_cxt *rx_cxt; + + struct urb *urb; + u8 *buf; + + void (*callback)(void *cb_data, void *data, int len); + void *cb_data; +}; + +struct rx_cxt { + struct list_head free_list; + struct list_head used_list; + spinlock_t lock; +}; + +struct usbwm_dev { + struct usb_device *usbdev; +#ifdef CONFIG_WIMAX_GDM72XX_USB_PM + struct work_struct pm_ws; + + struct usb_interface *intf; +#endif +#ifdef CONFIG_WIMAX_GDM72XX_K_MODE + int bw_switch; + struct list_head list; +#endif + + struct tx_cxt tx; + struct rx_cxt rx; + + int padding; +}; + +#endif /* __GDM_USB_H__ */ diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c new file mode 100644 index 0000000..f1936b9 --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -0,0 +1,1026 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/version.h> +#include <linux/etherdevice.h> +#include <asm/byteorder.h> +#include <linux/ip.h> +#include <linux/ipv6.h> +#include <linux/udp.h> +#include <linux/in.h> + +#include "gdm_wimax.h" +#include "hci.h" +#include "wm_ioctl.h" +#include "netlink_k.h" + +#define gdm_wimax_send(n, d, l) \ + (n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, NULL, NULL) +#define gdm_wimax_send_with_cb(n, d, l, c, b) \ + (n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, c, b) +#define gdm_wimax_rcv_with_cb(n, c, b) \ + (n->phy_dev->rcv_func)(n->phy_dev->priv_dev, c, b) + +#define EVT_MAX_SIZE 2048 + +struct evt_entry { + struct list_head list; + struct net_device *dev; + char evt_data[EVT_MAX_SIZE]; + int size; +}; + +static void __gdm_wimax_event_send(struct work_struct *work); +static inline struct evt_entry *alloc_event_entry(void); +static inline void free_event_entry(struct evt_entry *e); +static struct evt_entry *get_event_entry(void); +static void put_event_entry(struct evt_entry *e); + +static struct { + int ref_cnt; + struct sock *sock; + struct list_head evtq; + spinlock_t evt_lock; + + struct list_head freeq; + struct work_struct ws; +} wm_event; + +static u8 gdm_wimax_macaddr[6] = {0x00, 0x0a, 0x3b, 0xf0, 0x01, 0x30}; + +static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm); +static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up); + +#if defined(DEBUG_SDU) +static void printk_hex(u8 *buf, u32 size) +{ + int i; + + for (i = 0; i < size; i++) { + if (i && i % 16 == 0) + printk(KERN_DEBUG "\n%02x ", *buf++); + else + printk(KERN_DEBUG "%02x ", *buf++); + } + + printk(KERN_DEBUG "\n"); +} + +static const char *get_protocol_name(u16 protocol) +{ + static char buf[32]; + const char *name = "-"; + + switch (protocol) { + case ETH_P_ARP: + name = "ARP"; + break; + case ETH_P_IP: + name = "IP"; + break; + case ETH_P_IPV6: + name = "IPv6"; + break; + } + + sprintf(buf, "0x%04x(%s)", protocol, name); + return buf; +} + +static const char *get_ip_protocol_name(u8 ip_protocol) +{ + static char buf[32]; + const char *name = "-"; + + switch (ip_protocol) { + case IPPROTO_TCP: + name = "TCP"; + break; + case IPPROTO_UDP: + name = "UDP"; + break; + case IPPROTO_ICMP: + name = "ICMP"; + break; + } + + sprintf(buf, "%u(%s)", ip_protocol, name); + return buf; +} + +static const char *get_port_name(u16 port) +{ + static char buf[32]; + const char *name = "-"; + + switch (port) { + case 67: + name = "DHCP-Server"; + break; + case 68: + name = "DHCP-Client"; + break; + case 69: + name = "TFTP"; + break; + } + + sprintf(buf, "%u(%s)", port, name); + return buf; +} + +static void dump_eth_packet(const char *title, u8 *data, int len) +{ + struct iphdr *ih = NULL; + struct udphdr *uh = NULL; + u16 protocol = 0; + u8 ip_protocol = 0; + u16 port = 0; + + protocol = (data[12]<<8) | data[13]; + ih = (struct iphdr *) (data+ETH_HLEN); + + if (protocol == ETH_P_IP) { + uh = (struct udphdr *) ((char *)ih + sizeof(struct iphdr)); + ip_protocol = ih->protocol; + port = ntohs(uh->dest); + } else if (protocol == ETH_P_IPV6) { + struct ipv6hdr *i6h = (struct ipv6hdr *) data; + uh = (struct udphdr *) ((char *)i6h + sizeof(struct ipv6hdr)); + ip_protocol = i6h->nexthdr; + port = ntohs(uh->dest); + } + + printk(KERN_DEBUG "[%s] len=%d, %s, %s, %s\n", + title, len, + get_protocol_name(protocol), + get_ip_protocol_name(ip_protocol), + get_port_name(port)); + + #if 1 + if (!(data[0] == 0xff && data[1] == 0xff)) { + if (protocol == ETH_P_IP) { + printk(KERN_DEBUG " src=%u.%u.%u.%u\n", + NIPQUAD(ih->saddr)); + } else if (protocol == ETH_P_IPV6) { + #ifdef NIP6 + printk(KERN_DEBUG " src=%x:%x:%x:%x:%x:%x:%x:%x\n", + NIP6(ih->saddr)); + #else + printk(KERN_DEBUG " src=%pI6\n", &ih->saddr); + #endif + } + } + #endif + + #if (DUMP_PACKET & DUMP_SDU_ALL) + printk_hex(data, len); + #else + #if (DUMP_PACKET & DUMP_SDU_ARP) + if (protocol == ETH_P_ARP) + printk_hex(data, len); + #endif + #if (DUMP_PACKET & DUMP_SDU_IP) + if (protocol == ETH_P_IP || protocol == ETH_P_IPV6) + printk_hex(data, len); + #else + #if (DUMP_PACKET & DUMP_SDU_IP_TCP) + if (ip_protocol == IPPROTO_TCP) + printk_hex(data, len); + #endif + #if (DUMP_PACKET & DUMP_SDU_IP_UDP) + if (ip_protocol == IPPROTO_UDP) + printk_hex(data, len); + #endif + #if (DUMP_PACKET & DUMP_SDU_IP_ICMP) + if (ip_protocol == IPPROTO_ICMP) + printk_hex(data, len); + #endif + #endif + #endif +} +#endif + + +static inline int gdm_wimax_header(struct sk_buff **pskb) +{ + u16 buf[HCI_HEADER_SIZE / sizeof(u16)]; + struct sk_buff *skb = *pskb; + int ret = 0; + + if (unlikely(skb_headroom(skb) < HCI_HEADER_SIZE)) { + struct sk_buff *skb2; + + skb2 = skb_realloc_headroom(skb, HCI_HEADER_SIZE); + if (skb2 == NULL) + return -ENOMEM; + if (skb->sk) + skb_set_owner_w(skb2, skb->sk); + kfree_skb(skb); + skb = skb2; + } + + skb_push(skb, HCI_HEADER_SIZE); + buf[0] = H2B(WIMAX_TX_SDU); + buf[1] = H2B(skb->len - HCI_HEADER_SIZE); + memcpy(skb->data, buf, HCI_HEADER_SIZE); + + *pskb = skb; + return ret; +} + +static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg, + int len) +{ + struct nic *nic = netdev_priv(dev); + + #if defined(DEBUG_HCI) + u8 *buf = (u8 *) msg; + u16 hci_cmd = (buf[0]<<8) | buf[1]; + u16 hci_len = (buf[2]<<8) | buf[3]; + printk(KERN_DEBUG "H=>D: 0x%04x(%d)\n", hci_cmd, hci_len); + #endif + + gdm_wimax_send(nic, msg, len); +} + +static int gdm_wimax_event_init(void) +{ + if (wm_event.ref_cnt == 0) { + wm_event.sock = netlink_init(NETLINK_WIMAX, + gdm_wimax_event_rcv); + INIT_LIST_HEAD(&wm_event.evtq); + INIT_LIST_HEAD(&wm_event.freeq); + INIT_WORK(&wm_event.ws, __gdm_wimax_event_send); + spin_lock_init(&wm_event.evt_lock); + } + + if (wm_event.sock) { + wm_event.ref_cnt++; + return 0; + } + + printk(KERN_ERR "Creating WiMax Event netlink is failed\n"); + return -1; +} + +static void gdm_wimax_event_exit(void) +{ + if (wm_event.sock && --wm_event.ref_cnt == 0) { + struct evt_entry *e, *temp; + unsigned long flags; + + spin_lock_irqsave(&wm_event.evt_lock, flags); + + list_for_each_entry_safe(e, temp, &wm_event.evtq, list) { + list_del(&e->list); + free_event_entry(e); + } + list_for_each_entry_safe(e, temp, &wm_event.freeq, list) { + list_del(&e->list); + free_event_entry(e); + } + + spin_unlock_irqrestore(&wm_event.evt_lock, flags); + netlink_exit(wm_event.sock); + wm_event.sock = NULL; + } +} + +static inline struct evt_entry *alloc_event_entry(void) +{ + return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC); +} + +static inline void free_event_entry(struct evt_entry *e) +{ + kfree(e); +} + +static struct evt_entry *get_event_entry(void) +{ + struct evt_entry *e; + + if (list_empty(&wm_event.freeq)) + e = alloc_event_entry(); + else { + e = list_entry(wm_event.freeq.next, struct evt_entry, list); + list_del(&e->list); + } + + return e; +} + +static void put_event_entry(struct evt_entry *e) +{ + BUG_ON(!e); + + list_add_tail(&e->list, &wm_event.freeq); +} + +static void __gdm_wimax_event_send(struct work_struct *work) +{ + int idx; + unsigned long flags; + struct evt_entry *e; + + spin_lock_irqsave(&wm_event.evt_lock, flags); + + while (!list_empty(&wm_event.evtq)) { + e = list_entry(wm_event.evtq.next, struct evt_entry, list); + spin_unlock_irqrestore(&wm_event.evt_lock, flags); + + sscanf(e->dev->name, "wm%d", &idx); + netlink_send(wm_event.sock, idx, 0, e->evt_data, e->size); + + spin_lock_irqsave(&wm_event.evt_lock, flags); + list_del(&e->list); + put_event_entry(e); + } + + spin_unlock_irqrestore(&wm_event.evt_lock, flags); +} + +static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size) +{ + struct evt_entry *e; + unsigned long flags; + + #if defined(DEBUG_HCI) + u16 hci_cmd = ((u8)buf[0]<<8) | (u8)buf[1]; + u16 hci_len = ((u8)buf[2]<<8) | (u8)buf[3]; + printk(KERN_DEBUG "D=>H: 0x%04x(%d)\n", hci_cmd, hci_len); + #endif + + spin_lock_irqsave(&wm_event.evt_lock, flags); + + e = get_event_entry(); + if (!e) { + printk(KERN_ERR "%s: No memory for event\n", __func__); + spin_unlock_irqrestore(&wm_event.evt_lock, flags); + return -ENOMEM; + } + + e->dev = dev; + e->size = size; + memcpy(e->evt_data, buf, size); + + list_add_tail(&e->list, &wm_event.evtq); + spin_unlock_irqrestore(&wm_event.evt_lock, flags); + + schedule_work(&wm_event.ws); + + return 0; +} + +static void tx_complete(void *arg) +{ + struct nic *nic = arg; + + if (netif_queue_stopped(nic->netdev)) + netif_wake_queue(nic->netdev); +} + +int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev) +{ + int ret = 0; + struct nic *nic = netdev_priv(dev); + + ret = gdm_wimax_send_with_cb(nic, skb->data, skb->len, tx_complete, + nic); + if (ret == -ENOSPC) { + netif_stop_queue(dev); + ret = 0; + } + + if (ret) { + skb_pull(skb, HCI_HEADER_SIZE); + return ret; + } + + nic->stats.tx_packets++; + nic->stats.tx_bytes += skb->len - HCI_HEADER_SIZE; + kfree_skb(skb); + return ret; +} + +static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev) +{ + int ret = 0; + struct nic *nic = netdev_priv(dev); + struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf; + + #if defined(DEBUG_SDU) + dump_eth_packet("TX", skb->data, skb->len); + #endif + + ret = gdm_wimax_header(&skb); + if (ret < 0) { + skb_pull(skb, HCI_HEADER_SIZE); + return ret; + } + + #if !defined(LOOPBACK_TEST) + if (!fsm) + printk(KERN_ERR "ASSERTION ERROR: fsm is NULL!!\n"); + else if (fsm->m_status != M_CONNECTED) { + printk(KERN_EMERG "ASSERTION ERROR: Device is NOT ready. status=%d\n", + fsm->m_status); + kfree_skb(skb); + return 0; + } + #endif + +#if defined(CONFIG_WIMAX_GDM72XX_QOS) + ret = gdm_qos_send_hci_pkt(skb, dev); +#else + ret = gdm_wimax_send_tx(skb, dev); +#endif + return ret; +} + +static int gdm_wimax_set_config(struct net_device *dev, struct ifmap *map) +{ + if (dev->flags & IFF_UP) + return -EBUSY; + + return 0; +} + +static void __gdm_wimax_set_mac_addr(struct net_device *dev, char *mac_addr) +{ + u16 hci_pkt_buf[32 / sizeof(u16)]; + u8 *pkt = (u8 *) &hci_pkt_buf[0]; + struct nic *nic = netdev_priv(dev); + + /* Since dev is registered as a ethernet device, + * ether_setup has made dev->addr_len to be ETH_ALEN + */ + memcpy(dev->dev_addr, mac_addr, dev->addr_len); + + /* Let lower layer know of this change by sending + * SetInformation(MAC Address) + */ + hci_pkt_buf[0] = H2B(WIMAX_SET_INFO); /* cmd_evt */ + hci_pkt_buf[1] = H2B(8); /* size */ + pkt[4] = 0; /* T */ + pkt[5] = 6; /* L */ + memcpy(pkt + 6, mac_addr, dev->addr_len); /* V */ + + gdm_wimax_send(nic, pkt, HCI_HEADER_SIZE + 8); +} + +/* A driver function */ +static int gdm_wimax_set_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + + if (netif_running(dev)) + return -EBUSY; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + __gdm_wimax_set_mac_addr(dev, addr->sa_data); + + return 0; +} + +static struct net_device_stats *gdm_wimax_stats(struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + + return &nic->stats; +} + +static int gdm_wimax_open(struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf; + + netif_start_queue(dev); + + if (fsm && fsm->m_status != M_INIT) + gdm_wimax_ind_if_updown(dev, 1); + return 0; +} + +static int gdm_wimax_close(struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf; + + netif_stop_queue(dev); + + if (fsm && fsm->m_status != M_INIT) + gdm_wimax_ind_if_updown(dev, 0); + return 0; +} + +static void kdelete(void **buf) +{ + if (buf && *buf) { + kfree(*buf); + *buf = NULL; + } +} + +static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src) +{ + int size; + + size = dst->size < src->size ? dst->size : src->size; + + dst->size = size; + if (src->size) { + if (!dst->buf) + return -EINVAL; + if (copy_to_user(dst->buf, src->buf, size)) + return -EFAULT; + } + return 0; +} + +static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src) +{ + if (!src->size) { + dst->size = 0; + return 0; + } + + if (!src->buf) + return -EINVAL; + + if (!(dst->buf && dst->size == src->size)) { + kdelete(&dst->buf); + dst->buf = kmalloc(src->size, GFP_KERNEL); + if (dst->buf == NULL) + return -ENOMEM; + } + + if (copy_from_user(dst->buf, src->buf, src->size)) { + kdelete(&dst->buf); + return -EFAULT; + } + dst->size = src->size; + return 0; +} + +static void gdm_wimax_cleanup_ioctl(struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + int i; + + for (i = 0; i < SIOC_DATA_MAX; i++) + kdelete(&nic->sdk_data[i].buf); +} + +static void gdm_update_fsm(struct net_device *dev, struct fsm_s *new_fsm) +{ + struct nic *nic = netdev_priv(dev); + struct fsm_s *cur_fsm = + (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf; + + if (!cur_fsm) + return; + + if (cur_fsm->m_status != new_fsm->m_status || + cur_fsm->c_status != new_fsm->c_status) { + if (new_fsm->m_status == M_CONNECTED) + netif_carrier_on(dev); + else if (cur_fsm->m_status == M_CONNECTED) { + netif_carrier_off(dev); + #if defined(CONFIG_WIMAX_GDM72XX_QOS) + gdm_qos_release_list(nic); + #endif + } + gdm_wimax_ind_fsm_update(dev, new_fsm); + } +} + +static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct wm_req_s *req = (struct wm_req_s *) ifr; + struct nic *nic = netdev_priv(dev); + int ret; + + if (cmd != SIOCWMIOCTL) + return -EOPNOTSUPP; + + switch (req->cmd) { + case SIOCG_DATA: + case SIOCS_DATA: + if (req->data_id >= SIOC_DATA_MAX) { + printk(KERN_ERR + "%s error: data-index(%d) is invalid!!\n", + __func__, req->data_id); + return -EOPNOTSUPP; + } + if (req->cmd == SIOCG_DATA) { + ret = gdm_wimax_ioctl_get_data(&req->data, + &nic->sdk_data[req->data_id]); + if (ret < 0) + return ret; + } else if (req->cmd == SIOCS_DATA) { + if (req->data_id == SIOC_DATA_FSM) { + /*NOTE: gdm_update_fsm should be called + before gdm_wimax_ioctl_set_data is called*/ + gdm_update_fsm(dev, + (struct fsm_s *) req->data.buf); + } + ret = gdm_wimax_ioctl_set_data( + &nic->sdk_data[req->data_id], &req->data); + if (ret < 0) + return ret; + } + break; + default: + printk(KERN_ERR "%s: %x unknown ioctl\n", __func__, cmd); + return -EOPNOTSUPP; + } + + return 0; +} + +static void gdm_wimax_prepare_device(struct net_device *dev) +{ + struct nic *nic = netdev_priv(dev); + u16 buf[32 / sizeof(u16)]; + struct hci_s *hci = (struct hci_s *) buf; + u16 len = 0; + u32 val = 0; + + #define BIT_MULTI_CS 0 + #define BIT_WIMAX 1 + #define BIT_QOS 2 + #define BIT_AGGREGATION 3 + + /* GetInformation mac address */ + len = 0; + hci->cmd_evt = H2B(WIMAX_GET_INFO); + hci->data[len++] = TLV_T(T_MAC_ADDRESS); + hci->length = H2B(len); + gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len); + + val = (1<<BIT_WIMAX) | (1<<BIT_MULTI_CS); + #if defined(CONFIG_WIMAX_GDM72XX_QOS) + val |= (1<<BIT_QOS); + #endif + #if defined(CONFIG_WIMAX_GDM72XX_WIMAX2) + val |= (1<<BIT_AGGREGATION); + #endif + + /* Set capability */ + len = 0; + hci->cmd_evt = H2B(WIMAX_SET_INFO); + hci->data[len++] = TLV_T(T_CAPABILITY); + hci->data[len++] = TLV_L(T_CAPABILITY); + val = DH2B(val); + memcpy(&hci->data[len], &val, TLV_L(T_CAPABILITY)); + len += TLV_L(T_CAPABILITY); + hci->length = H2B(len); + gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len); + + printk(KERN_INFO "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val)); +} + +static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V) +{ + #define __U82U16(b) ((u16)((u8 *)(b))[0] | ((u16)((u8 *)(b))[1] << 8)) + int next_pos; + + *T = buf[0]; + if (buf[1] == 0x82) { + *L = B2H(__U82U16(&buf[2])); + next_pos = 1/*type*/+3/*len*/; + } else { + *L = buf[1]; + next_pos = 1/*type*/+1/*len*/; + } + *V = &buf[next_pos]; + + next_pos += *L/*length of val*/; + return next_pos; +} + +static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf, + int len) +{ + u8 T, *V; + u16 L; + u16 cmd_evt, cmd_len; + int pos = HCI_HEADER_SIZE; + + cmd_evt = B2H(*(u16 *)&buf[0]); + cmd_len = B2H(*(u16 *)&buf[2]); + + if (len < cmd_len + HCI_HEADER_SIZE) { + printk(KERN_ERR "%s: invalid length [%d/%d]\n", __func__, + cmd_len + HCI_HEADER_SIZE, len); + return -1; + } + + if (cmd_evt == WIMAX_GET_INFO_RESULT) { + if (cmd_len < 2) { + printk(KERN_ERR "%s: len is too short [%x/%d]\n", + __func__, cmd_evt, len); + return -1; + } + + pos += gdm_wimax_hci_get_tlv(&buf[pos], &T, &L, &V); + if (T == TLV_T(T_MAC_ADDRESS)) { + if (L != dev->addr_len) { + printk(KERN_ERR + "%s Invalid inofrmation result T/L " + "[%x/%d]\n", __func__, T, L); + return -1; + } + printk(KERN_INFO + "MAC change [%02x:%02x:%02x:%02x:%02x:%02x]" + "->[%02x:%02x:%02x:%02x:%02x:%02x]\n", + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], + V[0], V[1], V[2], V[3], V[4], V[5]); + memcpy(dev->dev_addr, V, dev->addr_len); + return 1; + } + } + + gdm_wimax_event_send(dev, buf, len); + return 0; +} + +static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len) +{ + struct nic *nic = netdev_priv(dev); + struct sk_buff *skb; + int ret; + + #if defined(DEBUG_SDU) + dump_eth_packet("RX", buf, len); + #endif + + skb = dev_alloc_skb(len + 2); + if (!skb) { + printk(KERN_ERR "%s: dev_alloc_skb failed!\n", __func__); + return; + } + skb_reserve(skb, 2); + + nic->stats.rx_packets++; + nic->stats.rx_bytes += len; + + memcpy(skb_put(skb, len), buf, len); + + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); /* what will happen? */ + + ret = in_interrupt() ? netif_rx(skb) : netif_rx_ni(skb); + if (ret == NET_RX_DROP) + printk(KERN_ERR "%s skb dropped\n", __func__); +} + +static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf, + int len) +{ + #define HCI_PADDING_BYTE 4 + #define HCI_RESERVED_BYTE 4 + struct hci_s *hci; + int length; + + while (len > 0) { + hci = (struct hci_s *) buf; + + if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) { + printk(KERN_ERR "Wrong cmd_evt(0x%04X)\n", + B2H(hci->cmd_evt)); + break; + } + + length = B2H(hci->length); + gdm_wimax_netif_rx(dev, hci->data, length); + + if (length & 0x3) { + /* Add padding size */ + length += HCI_PADDING_BYTE - (length & 0x3); + } + + length += HCI_HEADER_SIZE + HCI_RESERVED_BYTE; + len -= length; + buf += length; + } +} + +static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len) +{ + #if defined(CONFIG_WIMAX_GDM72XX_QOS) + struct nic *nic = netdev_priv(dev); + #endif + u16 cmd_evt, cmd_len; + + /* This code is added for certain rx packet to be ignored. */ + if (len == 0) + return; + + cmd_evt = B2H(*(u16 *)&buf[0]); + cmd_len = B2H(*(u16 *)&buf[2]); + + if (len < cmd_len + HCI_HEADER_SIZE) { + if (len) + printk(KERN_ERR "%s: invalid length [%d/%d]\n", + __func__, cmd_len + HCI_HEADER_SIZE, len); + return; + } + + switch (cmd_evt) { + case WIMAX_RX_SDU_AGGR: + gdm_wimax_transmit_aggr_pkt(dev, &buf[HCI_HEADER_SIZE], + cmd_len); + break; + case WIMAX_RX_SDU: + gdm_wimax_netif_rx(dev, &buf[HCI_HEADER_SIZE], cmd_len); + break; + #if defined(CONFIG_WIMAX_GDM72XX_QOS) + case WIMAX_EVT_MODEM_REPORT: + gdm_recv_qos_hci_packet(nic, buf, len); + break; + #endif + case WIMAX_SDU_TX_FLOW: + if (buf[4] == 0) { + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + } else if (buf[4] == 1) { + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + } + break; + default: + gdm_wimax_event_send(dev, buf, len); + break; + } +} + +static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm) +{ + u16 buf[32 / sizeof(u16)]; + u8 *hci_pkt_buf = (u8 *)&buf[0]; + + /* Indicate updating fsm */ + buf[0] = H2B(WIMAX_FSM_UPDATE); + buf[1] = H2B(sizeof(struct fsm_s)); + memcpy(&hci_pkt_buf[HCI_HEADER_SIZE], fsm, sizeof(struct fsm_s)); + + gdm_wimax_event_send(dev, hci_pkt_buf, + HCI_HEADER_SIZE + sizeof(struct fsm_s)); +} + +static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up) +{ + u16 buf[32 / sizeof(u16)]; + struct hci_s *hci = (struct hci_s *) buf; + unsigned char up_down; + + up_down = if_up ? WIMAX_IF_UP : WIMAX_IF_DOWN; + + /* Indicate updating fsm */ + hci->cmd_evt = H2B(WIMAX_IF_UPDOWN); + hci->length = H2B(sizeof(up_down)); + hci->data[0] = up_down; + + gdm_wimax_event_send(dev, (char *)hci, HCI_HEADER_SIZE+sizeof(up_down)); +} + +static void rx_complete(void *arg, void *data, int len) +{ + struct nic *nic = arg; + + gdm_wimax_transmit_pkt(nic->netdev, data, len); + gdm_wimax_rcv_with_cb(nic, rx_complete, nic); +} + +static void prepare_rx_complete(void *arg, void *data, int len) +{ + struct nic *nic = arg; + int ret; + + ret = gdm_wimax_get_prepared_info(nic->netdev, data, len); + if (ret == 1) + gdm_wimax_rcv_with_cb(nic, rx_complete, nic); + else { + if (ret < 0) + printk(KERN_ERR "get_prepared_info failed(%d)\n", ret); + gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic); + #if 0 + /* Re-prepare WiMax device */ + gdm_wimax_prepare_device(nic->netdev); + #endif + } +} + +static void start_rx_proc(struct nic *nic) +{ + gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic); +} + +static struct net_device_ops gdm_netdev_ops = { + .ndo_open = gdm_wimax_open, + .ndo_stop = gdm_wimax_close, + .ndo_set_config = gdm_wimax_set_config, + .ndo_start_xmit = gdm_wimax_tx, + .ndo_get_stats = gdm_wimax_stats, + .ndo_set_mac_address = gdm_wimax_set_mac_addr, + .ndo_do_ioctl = gdm_wimax_ioctl, +}; + +int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev) +{ + struct nic *nic = NULL; + struct net_device *dev; + int ret; + + dev = (struct net_device *)alloc_netdev(sizeof(*nic), + "wm%d", ether_setup); + + if (dev == NULL) { + printk(KERN_ERR "alloc_etherdev failed\n"); + return -ENOMEM; + } + + SET_NETDEV_DEV(dev, pdev); + dev->mtu = 1400; + dev->netdev_ops = &gdm_netdev_ops; + dev->flags &= ~IFF_MULTICAST; + memcpy(dev->dev_addr, gdm_wimax_macaddr, sizeof(gdm_wimax_macaddr)); + + nic = netdev_priv(dev); + memset(nic, 0, sizeof(*nic)); + + nic->netdev = dev; + nic->phy_dev = phy_dev; + phy_dev->netdev = dev; + + /* event socket init */ + ret = gdm_wimax_event_init(); + if (ret < 0) { + printk(KERN_ERR "Cannot create event.\n"); + goto cleanup; + } + + ret = register_netdev(dev); + if (ret) + goto cleanup; + + #if defined(LOOPBACK_TEST) + netif_start_queue(dev); + netif_carrier_on(dev); + #else + netif_carrier_off(dev); + #endif + +#ifdef CONFIG_WIMAX_GDM72XX_QOS + gdm_qos_init(nic); +#endif + + start_rx_proc(nic); + + /* Prepare WiMax device */ + gdm_wimax_prepare_device(dev); + + return 0; + +cleanup: + printk(KERN_ERR "register_netdev failed\n"); + free_netdev(dev); + return ret; +} + +void unregister_wimax_device(struct phy_dev *phy_dev) +{ + struct nic *nic = netdev_priv(phy_dev->netdev); + struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf; + + if (fsm) + fsm->m_status = M_INIT; + unregister_netdev(nic->netdev); + + gdm_wimax_event_exit(); + +#if defined(CONFIG_WIMAX_GDM72XX_QOS) + gdm_qos_release_list(nic); +#endif + + gdm_wimax_cleanup_ioctl(phy_dev->netdev); + + free_netdev(nic->netdev); +} diff --git a/drivers/staging/gdm72xx/gdm_wimax.h b/drivers/staging/gdm72xx/gdm_wimax.h new file mode 100644 index 0000000..023e649 --- /dev/null +++ b/drivers/staging/gdm72xx/gdm_wimax.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __GDM_WIMAX_H__ +#define __GDM_WIMAX_H__ + +#include <linux/netdevice.h> +#include <linux/version.h> +#include <linux/types.h> +#include "wm_ioctl.h" +#if defined(CONFIG_WIMAX_GDM72XX_QOS) +#include "gdm_qos.h" +#endif + +#define DRIVER_VERSION "3.2.3" + +/*#define ETH_P_IP 0x0800 */ +/*#define ETH_P_ARP 0x0806 */ +/*#define ETH_P_IPV6 0x86DD */ + +#define H2L(x) __cpu_to_le16(x) +#define L2H(x) __le16_to_cpu(x) +#define DH2L(x) __cpu_to_le32(x) +#define DL2H(x) __le32_to_cpu(x) + +#define H2B(x) __cpu_to_be16(x) +#define B2H(x) __be16_to_cpu(x) +#define DH2B(x) __cpu_to_be32(x) +#define DB2H(x) __be32_to_cpu(x) + +struct phy_dev { + void *priv_dev; + struct net_device *netdev; + + int (*send_func)(void *priv_dev, void *data, int len, + void (*cb)(void *cb_data), void *cb_data); + int (*rcv_func)(void *priv_dev, + void (*cb)(void *cb_data, void *data, int len), + void *cb_data); +}; + +struct nic { + struct net_device *netdev; + struct phy_dev *phy_dev; + + struct net_device_stats stats; + + struct data_s sdk_data[SIOC_DATA_MAX]; + +#if defined(CONFIG_WIMAX_GDM72XX_QOS) + struct qos_cb_s qos; +#endif + +}; + + +#if 0 +#define dprintk(fmt, args ...) printk(KERN_DEBUG " [GDM] " fmt, ## args) +#else +#define dprintk(...) +#endif + +/*#define DEBUG_SDU */ +#if defined(DEBUG_SDU) +#define DUMP_SDU_ALL (1<<0) +#define DUMP_SDU_ARP (1<<1) +#define DUMP_SDU_IP (1<<2) +#define DUMP_SDU_IP_TCP (1<<8) +#define DUMP_SDU_IP_UDP (1<<9) +#define DUMP_SDU_IP_ICMP (1<<10) +#define DUMP_PACKET (DUMP_SDU_ALL) +#endif + +/*#define DEBUG_HCI */ + +/*#define LOOPBACK_TEST */ + +extern int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev); +extern int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev); +extern void unregister_wimax_device(struct phy_dev *phy_dev); + +#endif diff --git a/drivers/staging/gdm72xx/hci.h b/drivers/staging/gdm72xx/hci.h new file mode 100644 index 0000000..0e06766 --- /dev/null +++ b/drivers/staging/gdm72xx/hci.h @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef HCI_H_20080801 +#define HCI_H_20080801 + +#define HCI_HEADER_SIZE 4 +#define HCI_VALUE_OFFS (HCI_HEADER_SIZE) +#define HCI_MAX_PACKET 2048 +#define HCI_MAX_PARAM (HCI_MAX_PACKET-HCI_HEADER_SIZE) +#define HCI_MAX_TLV 32 + +/* CMD-EVT */ + +/* Category 0 */ +#define WIMAX_RESET 0x0000 +#define WIMAX_SET_INFO 0x0001 +#define WIMAX_GET_INFO 0x0002 +#define WIMAX_GET_INFO_RESULT 0x8003 +#define WIMAX_RADIO_OFF 0x0004 +#define WIMAX_RADIO_ON 0x0006 +#define WIMAX_WIMAX_RESET 0x0007 /* Is this still here */ + +/* Category 1 */ +#define WIMAX_NET_ENTRY 0x0100 +#define WIMAX_NET_DISCONN 0x0102 +#define WIMAX_ENTER_SLEEP 0x0103 +#define WIMAX_EXIT_SLEEP 0x0104 +#define WIMAX_ENTER_IDLE 0x0105 +#define WIMAX_EXIT_IDLE 0x0106 +#define WIMAX_MODE_CHANGE 0x8108 +#define WIMAX_HANDOVER 0x8109 /* obsolete */ + +#define WIMAX_SCAN 0x010d +#define WIMAX_SCAN_COMPLETE 0x810e +#define WIMAX_SCAN_RESULT 0x810f + +#define WIMAX_CONNECT 0x0110 +#define WIMAX_CONNECT_START 0x8111 +#define WIMAX_CONNECT_COMPLETE 0x8112 +#define WIMAX_ASSOC_START 0x8113 +#define WIMAX_ASSOC_COMPLETE 0x8114 +#define WIMAX_DISCONN_IND 0x8115 +#define WIMAX_ENTRY_IND 0x8116 +#define WIMAX_HO_START 0x8117 +#define WIMAX_HO_COMPLETE 0x8118 +#define WIMAX_RADIO_STATE_IND 0x8119 +#define WIMAX_IP_RENEW_IND 0x811a + +#define WIMAX_DISCOVER_NSP 0x011d +#define WIMAX_DISCOVER_NSP_RESULT 0x811e + +#define WIMAX_SDU_TX_FLOW 0x8125 + +/* Category 2 */ +#define WIMAX_TX_EAP 0x0200 +#define WIMAX_RX_EAP 0x8201 +#define WIMAX_TX_SDU 0x0202 +#define WIMAX_RX_SDU 0x8203 +#define WIMAX_RX_SDU_AGGR 0x8204 +#define WIMAX_TX_SDU_AGGR 0x0205 + +/* Category 3 */ +#define WIMAX_DM_CMD 0x030a +#define WIMAX_DM_RSP 0x830b + +#define WIMAX_CLI_CMD 0x030c +#define WIMAX_CLI_RSP 0x830d + +#define WIMAX_DL_IMAGE 0x0310 +#define WIMAX_DL_IMAGE_STATUS 0x8311 +#define WIMAX_UL_IMAGE 0x0312 +#define WIMAX_UL_IMAGE_RESULT 0x8313 +#define WIMAX_UL_IMAGE_STATUS 0x0314 + +#define WIMAX_EVT_MODEM_REPORT 0x8325 + +/* Category 0xF */ +#define WIMAX_FSM_UPDATE 0x8F01 +#define WIMAX_IF_UPDOWN 0x8F02 + #define WIMAX_IF_UP 1 + #define WIMAX_IF_DOWN 2 + +/* WIMAX mode */ +#define W_NULL 0 +#define W_STANDBY 1 +#define W_OOZ 2 +#define W_AWAKE 3 +#define W_IDLE 4 +#define W_SLEEP 5 +#define W_WAIT 6 + +#define W_NET_ENTRY_RNG 0x80 +#define W_NET_ENTRY_SBC 0x81 +#define W_NET_ENTRY_PKM 0x82 +#define W_NET_ENTRY_REG 0x83 +#define W_NET_ENTRY_DSX 0x84 + +#define W_NET_ENTRY_RNG_FAIL 0x1100100 +#define W_NET_ENTRY_SBC_FAIL 0x1100200 +#define W_NET_ENTRY_PKM_FAIL 0x1102000 +#define W_NET_ENTRY_REG_FAIL 0x1103000 +#define W_NET_ENTRY_DSX_FAIL 0x1104000 + +/* Scan Type */ +#define W_SCAN_ALL_CHANNEL 0 +#define W_SCAN_ALL_SUBSCRIPTION 1 +#define W_SCAN_SPECIFIED_SUBSCRIPTION 2 + +/* + * TLV + * + * [31:31] indicates the type is composite. + * [30:16] is the length of the type. 0 length means length is variable. + * [15:0] is the actual type. + * + */ +#define TLV_L(x) (((x) >> 16) & 0xff) +#define TLV_T(x) ((x) & 0xff) +#define TLV_COMPOSITE(x) ((x) >> 31) + +/* GENERAL */ +#define T_MAC_ADDRESS (0x00 | (6 << 16)) +#define T_BSID (0x01 | (6 << 16)) +#define T_MSK (0x02 | (64 << 16)) +#define T_RSSI_THRSHLD (0x03 | (1 << 16)) +#define T_FREQUENCY (0x04 | (4 << 16)) +#define T_CONN_CS_TYPE (0x05 | (1 << 16)) +#define T_HOST_IP_VER (0x06 | (1 << 16)) +#define T_STBY_SCAN_INTERVAL (0x07 | (4 << 16)) +#define T_OOZ_SCAN_INTERVAL (0x08 | (4 << 16)) +#define T_IMEI (0x09 | (8 << 16)) +#define T_PID (0x0a | (12 << 16)) + +#define T_CAPABILITY (0x1a | (4 << 16)) +#define T_RELEASE_NUMBER (0x1b | (4 << 16)) +#define T_DRIVER_REVISION (0x1c | (4 << 16)) +#define T_FW_REVISION (0x1d | (4 << 16)) +#define T_MAC_HW_REVISION (0x1e | (4 << 16)) +#define T_PHY_HW_REVISION (0x1f | (4 << 16)) + +/* HANDOVER */ +#define T_SCAN_INTERVAL (0x20 | (1 << 16)) + +#define T_RSC_RETAIN_TIME (0x2f | (2 << 16)) + +/* SLEEP */ +#define T_TYPE1_ISW (0x40 | (1 << 16)) + +#define T_SLP_START_TO (0x4a | (2 << 16)) + +/* IDLE */ +#define T_IDLE_MODE_TO (0x50 | (2 << 16)) + +#define T_IDLE_START_TO (0x54 | (2 << 16)) + +/* MONITOR */ +#define T_RSSI (0x60 | (1 << 16)) +#define T_CINR (0x61 | (1 << 16)) +#define T_TX_POWER (0x6a | (1 << 16)) +#define T_CUR_FREQ (0x7f | (4 << 16)) + + +/* WIMAX */ +#define T_MAX_SUBSCRIPTION (0xa1 | (1 << 16)) +#define T_MAX_SF (0xa2 | (1 << 16)) +#define T_PHY_TYPE (0xa3 | (1 << 16)) +#define T_PKM (0xa4 | (1 << 16)) +#define T_AUTH_POLICY (0xa5 | (1 << 16)) +#define T_CS_TYPE (0xa6 | (2 << 16)) +#define T_VENDOR_NAME (0xa7 | (0 << 16)) +#define T_MOD_NAME (0xa8 | (0 << 16)) +#define T_PACKET_FILTER (0xa9 | (1 << 16)) +#define T_NSP_CHANGE_COUNT (0xaa | (4 << 16)) +#define T_RADIO_STATE (0xab | (1 << 16)) +#define T_URI_CONTACT_TYPE (0xac | (1 << 16)) +#define T_URI_TEXT (0xad | (0 << 16)) +#define T_URI (0xae | (0 << 16)) +#define T_ENABLE_AUTH (0xaf | (1 << 16)) +#define T_TIMEOUT (0xb0 | (2 << 16)) +#define T_RUN_MODE (0xb1 | (1 << 16)) +#define T_OMADMT_VER (0xb2 | (4 << 16)) +/* This is measured in seconds from 00:00:00 GMT January 1, 1970. */ +#define T_RTC_TIME (0xb3 | (4 << 16)) +#define T_CERT_STATUS (0xb4 | (4 << 16)) +#define T_CERT_MASK (0xb5 | (4 << 16)) +#define T_EMSK (0xb6 | (64 << 16)) + +/* Subscription TLV */ +#define T_SUBSCRIPTION_LIST (0xd1 | (0 << 16) | (1 << 31)) +#define T_H_NSPID (0xd2 | (3 << 16)) +#define T_NSP_NAME (0xd3 | (0 << 16)) +#define T_SUBSCRIPTION_NAME (0xd4 | (0 << 16)) +#define T_SUBSCRIPTION_FLAG (0xd5 | (2 << 16)) +#define T_V_NSPID (0xd6 | (3 << 16)) +#define T_NAP_ID (0xd7 | (3 << 16)) +#define T_PREAMBLES (0xd8 | (15 << 16)) +#define T_BW (0xd9 | (4 << 16)) +#define T_FFTSIZE (0xda | (4 << 16)) +#define T_DUPLEX_MODE (0xdb | (4 << 16)) + +struct hci_s { + unsigned short cmd_evt; + unsigned short length; + unsigned char data[0]; +} __packed; + +#endif diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c new file mode 100644 index 0000000..292af0f --- /dev/null +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/etherdevice.h> +#include <linux/netlink.h> +#include <asm/byteorder.h> +#include <net/sock.h> + +#if !defined(NLMSG_HDRLEN) +#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) +#endif + +#define ND_MAX_GROUP 30 +#define ND_IFINDEX_LEN sizeof(int) +#define ND_NLMSG_SPACE(len) (NLMSG_SPACE(len) + ND_IFINDEX_LEN) +#define ND_NLMSG_DATA(nlh) \ + ((void *)((char *)NLMSG_DATA(nlh) + ND_IFINDEX_LEN)) +#define ND_NLMSG_S_LEN(len) (len+ND_IFINDEX_LEN) +#define ND_NLMSG_R_LEN(nlh) (nlh->nlmsg_len-ND_IFINDEX_LEN) +#define ND_NLMSG_IFIDX(nlh) NLMSG_DATA(nlh) +#define ND_MAX_MSG_LEN 8096 + +#if defined(DEFINE_MUTEX) +static DEFINE_MUTEX(netlink_mutex); +#else +static struct semaphore netlink_mutex; +#define mutex_lock(x) down(x) +#define mutex_unlock(x) up(x) +#endif + +static void (*rcv_cb)(struct net_device *dev, u16 type, void *msg, int len); + +static void netlink_rcv_cb(struct sk_buff *skb) +{ + struct nlmsghdr *nlh; + struct net_device *dev; + u32 mlen; + void *msg; + int ifindex; + + if (skb->len >= NLMSG_SPACE(0)) { + nlh = (struct nlmsghdr *)skb->data; + + if (skb->len < nlh->nlmsg_len || + nlh->nlmsg_len > ND_MAX_MSG_LEN) { + printk(KERN_ERR "Invalid length (%d,%d)\n", skb->len, + nlh->nlmsg_len); + return; + } + + memcpy(&ifindex, ND_NLMSG_IFIDX(nlh), ND_IFINDEX_LEN); + msg = ND_NLMSG_DATA(nlh); + mlen = ND_NLMSG_R_LEN(nlh); + + if (rcv_cb) { + dev = dev_get_by_index(&init_net, ifindex); + if (dev) { + rcv_cb(dev, nlh->nlmsg_type, msg, mlen); + dev_put(dev); + } else + printk(KERN_ERR "dev_get_by_index(%d) " + "is not found.\n", ifindex); + } else + printk(KERN_ERR "Unregistered Callback\n"); + } +} + +static void netlink_rcv(struct sk_buff *skb) +{ + mutex_lock(&netlink_mutex); + netlink_rcv_cb(skb); + mutex_unlock(&netlink_mutex); +} + +struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, + void *msg, int len)) +{ + struct sock *sock; + +#if !defined(DEFINE_MUTEX) + init_MUTEX(&netlink_mutex); +#endif + + sock = netlink_kernel_create(&init_net, unit, 0, netlink_rcv, NULL, + THIS_MODULE); + + if (sock) + rcv_cb = cb; + + return sock; +} + +void netlink_exit(struct sock *sock) +{ + sock_release(sock->sk_socket); +} + +int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) +{ + static u32 seq; + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + int ret = 0; + + if (group > ND_MAX_GROUP) { + printk(KERN_ERR "Group %d is invalied.\n", group); + printk(KERN_ERR "Valid group is 0 ~ %d.\n", ND_MAX_GROUP); + return -EINVAL; + } + + skb = alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC); + if (!skb) { + printk(KERN_ERR "netlink_broadcast ret=%d\n", ret); + return -ENOMEM; + } + + seq++; + nlh = NLMSG_PUT(skb, 0, seq, type, len); + memcpy(NLMSG_DATA(nlh), msg, len); + + NETLINK_CB(skb).pid = 0; + NETLINK_CB(skb).dst_group = 0; + + ret = netlink_broadcast(sock, skb, 0, group+1, GFP_ATOMIC); + + if (!ret) + return len; + else { + if (ret != -ESRCH) { + printk(KERN_ERR "netlink_broadcast g=%d, t=%d, l=%d, r=%d\n", + group, type, len, ret); + } + ret = 0; + } + +nlmsg_failure: + return ret; +} diff --git a/drivers/staging/gdm72xx/netlink_k.h b/drivers/staging/gdm72xx/netlink_k.h new file mode 100644 index 0000000..1dffaa6 --- /dev/null +++ b/drivers/staging/gdm72xx/netlink_k.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if !defined(NETLINK_H_20081202) +#define NETLINK_H_20081202 +#include <linux/netdevice.h> +#include <net/sock.h> + +struct sock *netlink_init(int unit, + void (*cb)(struct net_device *dev, u16 type, void *msg, int len)); +void netlink_exit(struct sock *sock); +int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len); + +#endif diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c new file mode 100644 index 0000000..6ff4dc3 --- /dev/null +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <linux/fs.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <linux/mmc/core.h> +#include <linux/mmc/card.h> +#include <linux/mmc/sdio_func.h> + +#include "gdm_sdio.h" + +#define TYPE_A_HEADER_SIZE 4 +#define TYPE_A_LOOKAHEAD_SIZE 16 +#define YMEM0_SIZE 0x8000 /* 32kbytes */ +#define DOWNLOAD_SIZE (YMEM0_SIZE - TYPE_A_HEADER_SIZE) + +#define KRN_PATH "/lib/firmware/gdm72xx/gdmskrn.bin" +#define RFS_PATH "/lib/firmware/gdm72xx/gdmsrfs.bin" + +static u8 *tx_buf; + +static int ack_ready(struct sdio_func *func) +{ + unsigned long start = jiffies; + u8 val; + int ret; + + while ((jiffies - start) < HZ) { + val = sdio_readb(func, 0x13, &ret); + if (val & 0x01) + return 1; + schedule(); + } + + return 0; +} + +static int download_image(struct sdio_func *func, char *img_name) +{ + int ret = 0, len, size, pno; + struct file *filp = NULL; + struct inode *inode = NULL; + u8 *buf = tx_buf; + loff_t pos = 0; + + filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(filp)) { + printk(KERN_ERR "Can't find %s.\n", img_name); + return -ENOENT; + } + + if (filp->f_dentry) + inode = filp->f_dentry->d_inode; + if (!inode || !S_ISREG(inode->i_mode)) { + printk(KERN_ERR "Invalid file type: %s\n", img_name); + ret = -EINVAL; + goto out; + } + + size = i_size_read(inode->i_mapping->host); + if (size <= 0) { + printk(KERN_ERR "Unable to find file size: %s\n", img_name); + ret = size; + goto out; + } + + pno = 0; + while ((len = filp->f_op->read(filp, buf + TYPE_A_HEADER_SIZE, + DOWNLOAD_SIZE, &pos))) { + if (len < 0) { + ret = -1; + goto out; + } + + buf[0] = len & 0xff; + buf[1] = (len >> 8) & 0xff; + buf[2] = (len >> 16) & 0xff; + + if (pos >= size) /* The last packet */ + buf[3] = 2; + else + buf[3] = 0; + + ret = sdio_memcpy_toio(func, 0, buf, len + TYPE_A_HEADER_SIZE); + if (ret < 0) { + printk(KERN_ERR "gdmwm: send image error: " + "packet number = %d ret = %d\n", pno, ret); + goto out; + } + if (buf[3] == 2) /* The last packet */ + break; + if (!ack_ready(func)) { + ret = -EIO; + printk(KERN_ERR "gdmwm: Ack is not ready.\n"); + goto out; + } + ret = sdio_memcpy_fromio(func, buf, 0, TYPE_A_LOOKAHEAD_SIZE); + if (ret < 0) { + printk(KERN_ERR "gdmwm: receive ack error: " + "packet number = %d ret = %d\n", pno, ret); + goto out; + } + sdio_writeb(func, 0x01, 0x13, &ret); + sdio_writeb(func, 0x00, 0x10, &ret); /* PCRRT */ + + pno++; + } +out: + filp_close(filp, current->files); + return ret; +} + +int sdio_boot(struct sdio_func *func) +{ + static mm_segment_t fs; + int ret; + + tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL); + if (tx_buf == NULL) { + printk(KERN_ERR "Error: kmalloc: %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + + fs = get_fs(); + set_fs(get_ds()); + + ret = download_image(func, KRN_PATH); + if (ret) + goto restore_fs; + printk(KERN_INFO "GCT: Kernel download success.\n"); + + ret = download_image(func, RFS_PATH); + if (ret) + goto restore_fs; + printk(KERN_INFO "GCT: Filesystem download success.\n"); + +restore_fs: + set_fs(fs); + kfree(tx_buf); + return ret; +} diff --git a/drivers/staging/gdm72xx/sdio_boot.h b/drivers/staging/gdm72xx/sdio_boot.h new file mode 100644 index 0000000..373ac28 --- /dev/null +++ b/drivers/staging/gdm72xx/sdio_boot.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SDIO_BOOT_H__ +#define __SDIO_BOOT_H__ + +struct sdio_func; + +extern int sdio_boot(struct sdio_func *func); + +#endif /* __SDIO_BOOT_H__ */ diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c new file mode 100644 index 0000000..5a0e030 --- /dev/null +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/uaccess.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/usb.h> +#include <linux/unistd.h> +#include <linux/slab.h> + +#include <asm/byteorder.h> +#include "gdm_usb.h" +#include "usb_boot.h" + +#define DN_KERNEL_MAGIC_NUMBER 0x10760001 +#define DN_ROOTFS_MAGIC_NUMBER 0x10760002 + +#define DOWNLOAD_SIZE 1024 + +#define DH2B(x) __cpu_to_be32(x) +#define DL2H(x) __le32_to_cpu(x) + +#define MIN(a, b) ((a) > (b) ? (b) : (a)) + +#define MAX_IMG_CNT 16 +#define UIMG_PATH "/lib/firmware/gdm72xx/gdmuimg.bin" +#define KERN_PATH "/lib/firmware/gdm72xx/zImage" +#define FS_PATH "/lib/firmware/gdm72xx/ramdisk.jffs2" + +struct dn_header { + u32 magic_num; + u32 file_size; +}; + +struct img_header { + u32 magic_code; + u32 count; + u32 len; + u32 offset[MAX_IMG_CNT]; + char hostname[32]; + char date[32]; +}; + +struct fw_info { + u32 id; + u32 len; + u32 kernel_len; + u32 rootfs_len; + u32 kernel_offset; + u32 rootfs_offset; + u32 fw_ver; + u32 mac_ver; + char hostname[32]; + char userid[16]; + char date[32]; + char user_desc[128]; +}; + +static void array_le32_to_cpu(u32 *arr, int num) +{ + int i; + for (i = 0; i < num; i++, arr++) + *arr = DL2H(*arr); +} + +static u8 *tx_buf; + +static int gdm_wibro_send(struct usb_device *usbdev, void *data, int len) +{ + int ret; + int actual; + + ret = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), data, len, + &actual, 1000); + + if (ret < 0) { + printk(KERN_ERR "Error : usb_bulk_msg ( result = %d )\n", ret); + return ret; + } + return 0; +} + +static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len) +{ + int ret; + int actual; + + ret = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), data, len, + &actual, 5000); + + if (ret < 0) { + printk(KERN_ERR "Error : usb_bulk_msg(recv) ( result = %d )\n", + ret); + return ret; + } + return 0; +} + +static int download_image(struct usb_device *usbdev, struct file *filp, + loff_t *pos, u32 img_len, u32 magic_num) +{ + struct dn_header h; + int ret = 0; + u32 size; + int len, readn; + + size = (img_len + DOWNLOAD_SIZE - 1) & ~(DOWNLOAD_SIZE - 1); + h.magic_num = DH2B(magic_num); + h.file_size = DH2B(size); + + ret = gdm_wibro_send(usbdev, &h, sizeof(h)); + if (ret < 0) + goto out; + + readn = 0; + while ((len = filp->f_op->read(filp, tx_buf, DOWNLOAD_SIZE, pos))) { + + if (len < 0) { + ret = -1; + goto out; + } + readn += len; + + ret = gdm_wibro_send(usbdev, tx_buf, DOWNLOAD_SIZE); + if (ret < 0) + goto out; + if (readn >= img_len) + break; + } + + if (readn < img_len) { + printk(KERN_ERR "gdmwm: Cannot read to the requested size. " + "Read = %d Requested = %d\n", readn, img_len); + ret = -EIO; + } +out: + + return ret; +} + +int usb_boot(struct usb_device *usbdev, u16 pid) +{ + int i, ret = 0; + struct file *filp = NULL; + struct inode *inode = NULL; + static mm_segment_t fs; + struct img_header hdr; + struct fw_info fw_info; + loff_t pos = 0; + char *img_name = UIMG_PATH; + int len; + + tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL); + if (tx_buf == NULL) { + printk(KERN_ERR "Error: kmalloc\n"); + return -ENOMEM; + } + + fs = get_fs(); + set_fs(get_ds()); + + filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(filp)) { + printk(KERN_ERR "Can't find %s.\n", img_name); + set_fs(fs); + ret = -ENOENT; + goto restore_fs; + } + + if (filp->f_dentry) + inode = filp->f_dentry->d_inode; + if (!inode || !S_ISREG(inode->i_mode)) { + printk(KERN_ERR "Invalid file type: %s\n", img_name); + ret = -EINVAL; + goto out; + } + + len = filp->f_op->read(filp, (u8 *)&hdr, sizeof(hdr), &pos); + if (len != sizeof(hdr)) { + printk(KERN_ERR "gdmwm: Cannot read the image info.\n"); + ret = -EIO; + goto out; + } + + array_le32_to_cpu((u32 *)&hdr, 19); +#if 0 + if (hdr.magic_code != 0x10767fff) { + printk(KERN_ERR "gdmwm: Invalid magic code 0x%08x\n", + hdr.magic_code); + ret = -EINVAL; + goto out; + } +#endif + if (hdr.count > MAX_IMG_CNT) { + printk(KERN_ERR "gdmwm: Too many images. %d\n", hdr.count); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < hdr.count; i++) { + if (hdr.offset[i] > hdr.len) { + printk(KERN_ERR "gdmwm: Invalid offset. " + "Entry = %d Offset = 0x%08x " + "Image length = 0x%08x\n", + i, hdr.offset[i], hdr.len); + ret = -EINVAL; + goto out; + } + + pos = hdr.offset[i]; + len = filp->f_op->read(filp, (u8 *)&fw_info, sizeof(fw_info), + &pos); + if (len != sizeof(fw_info)) { + printk(KERN_ERR "gdmwm: Cannot read the FW info.\n"); + ret = -EIO; + goto out; + } + + array_le32_to_cpu((u32 *)&fw_info, 8); +#if 0 + if ((fw_info.id & 0xfffff000) != 0x10767000) { + printk(KERN_ERR "gdmwm: Invalid FW id. 0x%08x\n", + fw_info.id); + ret = -EIO; + goto out; + } +#endif + + if ((fw_info.id & 0xffff) != pid) + continue; + + pos = hdr.offset[i] + fw_info.kernel_offset; + ret = download_image(usbdev, filp, &pos, fw_info.kernel_len, + DN_KERNEL_MAGIC_NUMBER); + if (ret < 0) + goto out; + printk(KERN_INFO "GCT: Kernel download success.\n"); + + pos = hdr.offset[i] + fw_info.rootfs_offset; + ret = download_image(usbdev, filp, &pos, fw_info.rootfs_len, + DN_ROOTFS_MAGIC_NUMBER); + if (ret < 0) + goto out; + printk(KERN_INFO "GCT: Filesystem download success.\n"); + + break; + } + + if (i == hdr.count) { + printk(KERN_ERR "Firmware for gsk%x is not installed.\n", pid); + ret = -EINVAL; + } +out: + filp_close(filp, current->files); + +restore_fs: + set_fs(fs); + kfree(tx_buf); + return ret; +} + +/*#define GDM7205_PADDING 256 */ +#define DOWNLOAD_CHUCK 2048 +#define KERNEL_TYPE_STRING "linux" +#define FS_TYPE_STRING "rootfs" + +static int em_wait_ack(struct usb_device *usbdev, int send_zlp) +{ + int ack; + int ret = -1; + + if (send_zlp) { + /*Send ZLP*/ + ret = gdm_wibro_send(usbdev, NULL, 0); + if (ret < 0) + goto out; + } + + /*Wait for ACK*/ + ret = gdm_wibro_recv(usbdev, &ack, sizeof(ack)); + if (ret < 0) + goto out; +out: + return ret; +} + +static int em_download_image(struct usb_device *usbdev, char *path, + char *type_string) +{ + struct file *filp; + struct inode *inode; + static mm_segment_t fs; + char *buf = NULL; + loff_t pos = 0; + int ret = 0; + int len, readn = 0; + #if defined(GDM7205_PADDING) + const int pad_size = GDM7205_PADDING; + #else + const int pad_size = 0; + #endif + + fs = get_fs(); + set_fs(get_ds()); + + filp = filp_open(path, O_RDONLY | O_LARGEFILE, 0); + if (IS_ERR(filp)) { + printk(KERN_ERR "Can't find %s.\n", path); + set_fs(fs); + ret = -ENOENT; + goto restore_fs; + } + + if (filp->f_dentry) { + inode = filp->f_dentry->d_inode; + if (!inode || !S_ISREG(inode->i_mode)) { + printk(KERN_ERR "Invalid file type: %s\n", path); + ret = -EINVAL; + goto out; + } + } + + buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); + if (buf == NULL) { + printk(KERN_ERR "Error: kmalloc\n"); + return -ENOMEM; + } + + strcpy(buf+pad_size, type_string); + ret = gdm_wibro_send(usbdev, buf, strlen(type_string)+pad_size); + if (ret < 0) + goto out; + + while ((len = filp->f_op->read(filp, buf+pad_size, DOWNLOAD_CHUCK, + &pos))) { + if (len < 0) { + ret = -1; + goto out; + } + readn += len; + + ret = gdm_wibro_send(usbdev, buf, len+pad_size); + if (ret < 0) + goto out; + + ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0)); + if (ret < 0) + goto out; + } + + ret = em_wait_ack(usbdev, 1); + if (ret < 0) + goto out; + +out: + filp_close(filp, current->files); + +restore_fs: + set_fs(fs); + + kfree(buf); + + return ret; +} + +static int em_fw_reset(struct usb_device *usbdev) +{ + int ret; + + /*Send ZLP*/ + ret = gdm_wibro_send(usbdev, NULL, 0); + return ret; +} + +int usb_emergency(struct usb_device *usbdev) +{ + int ret; + + ret = em_download_image(usbdev, KERN_PATH, KERNEL_TYPE_STRING); + if (ret < 0) + goto out; + printk(KERN_INFO "GCT Emergency: Kernel download success.\n"); + + ret = em_download_image(usbdev, FS_PATH, FS_TYPE_STRING); + if (ret < 0) + goto out; + printk(KERN_INFO "GCT Emergency: Filesystem download success.\n"); + + ret = em_fw_reset(usbdev); +out: + return ret; +} diff --git a/drivers/staging/gdm72xx/usb_boot.h b/drivers/staging/gdm72xx/usb_boot.h new file mode 100644 index 0000000..c715cd3 --- /dev/null +++ b/drivers/staging/gdm72xx/usb_boot.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __USB_BOOT_H__ +#define __USB_BOOT_H__ + +struct usb_device; + +extern int usb_boot(struct usb_device *usbdev, u16 pid); +extern int usb_emergency(struct usb_device *usbdev); + +#endif /* __USB_BOOT_H__ */ diff --git a/drivers/staging/gdm72xx/usb_ids.h b/drivers/staging/gdm72xx/usb_ids.h new file mode 100644 index 0000000..b34616b --- /dev/null +++ b/drivers/staging/gdm72xx/usb_ids.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __USB_IDS_H__ +#define __USB_IDS_H__ + +/*You can replace vendor-ID as yours.*/ +#define GCT_VID 0x1076 + +/*You can replace product-ID as yours.*/ +#define GCT_PID1 0x7e00 +#define GCT_PID2 0x7f00 + +#define USB_DEVICE_ID_MATCH_DEVICE_INTERFACE \ + (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_CLASS) + +#define USB_DEVICE_INTF(vend, prod, intf) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE_INTERFACE, \ + .idVendor = (vend), .idProduct = (prod), .bInterfaceClass = (intf) + +#define EMERGENCY_PID 0x720f +#define BL_PID_MASK 0xffc0 + +#define USB_DEVICE_BOOTLOADER(vid, pid) \ + {USB_DEVICE((vid), ((pid)&BL_PID_MASK)|B_DOWNLOAD)}, \ + {USB_DEVICE((vid), ((pid)&BL_PID_MASK)|B_DOWNLOAD|B_DIFF_DL_DRV)} + +#define USB_DEVICE_CDC_DATA(vid, pid) \ + {USB_DEVICE_INTF((vid), (pid), USB_CLASS_CDC_DATA)} + +static const struct usb_device_id id_table[] = { + USB_DEVICE_BOOTLOADER(GCT_VID, GCT_PID1), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x1), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x2), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x3), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x4), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x5), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x6), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x7), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x8), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0x9), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xa), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xb), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xc), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xd), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xe), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID1+0xf), + + USB_DEVICE_BOOTLOADER(GCT_VID, GCT_PID2), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x1), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x2), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x3), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x4), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x5), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x6), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x7), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x8), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0x9), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xa), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xb), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xc), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xd), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xe), + USB_DEVICE_CDC_DATA(GCT_VID, GCT_PID2+0xf), + + {USB_DEVICE(GCT_VID, EMERGENCY_PID)}, + { } +}; + +#endif /* __USB_IDS_H__ */ diff --git a/drivers/staging/gdm72xx/wm_ioctl.h b/drivers/staging/gdm72xx/wm_ioctl.h new file mode 100644 index 0000000..9f46e06 --- /dev/null +++ b/drivers/staging/gdm72xx/wm_ioctl.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if !defined(WM_IOCTL_H_20080714) +#define WM_IOCTL_H_20080714 +#if !defined(__KERNEL__) +#include <net/if.h> +#endif + +#define NETLINK_WIMAX 31 + +#define SIOCWMIOCTL SIOCDEVPRIVATE + +#define SIOCG_DATA 0x8D10 +#define SIOCS_DATA 0x8D11 + +enum { + SIOC_DATA_FSM, + SIOC_DATA_NETLIST, + SIOC_DATA_CONNNSP, + SIOC_DATA_CONNCOMP, + SIOC_DATA_PROFILEID, + + SIOC_DATA_END +}; + +#define SIOC_DATA_MAX 16 + +/* FSM */ +enum { + M_INIT = 0, + M_OPEN_OFF, + M_OPEN_ON, + M_SCAN, + M_CONNECTING, + M_CONNECTED, + M_FSM_END, + + C_INIT = 0, + C_CONNSTART, + C_ASSOCSTART, + C_RNG, + C_SBC, + C_AUTH, + C_REG, + C_DSX, + C_ASSOCCOMPLETE, + C_CONNCOMPLETE, + C_FSM_END, + + D_INIT = 0, + D_READY, + D_LISTEN, + D_IPACQUISITION, + + END_FSM +}; + +struct fsm_s { + int m_status; /*main status*/ + int c_status; /*connection status*/ + int d_status; /*oma-dm status*/ +}; + +struct data_s { + int size; + void *buf; +}; + +struct wm_req_s { + union { + char ifrn_name[IFNAMSIZ]; + } ifr_ifrn; + + unsigned short cmd; + + unsigned short data_id; + struct data_s data; + +/* NOTE: sizeof(struct wm_req_s) must be less than sizeof(struct ifreq). */ +}; + +#ifndef ifr_name +#define ifr_name ifr_ifrn.ifrn_name +#endif + +#endif diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 8926f24..0338c7c 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -8,7 +8,7 @@ The crucial structure for device drivers in iio is iio_dev. First allocate one using: -struct iio_dev *indio_dev = iio_allocate_device(sizeof(struct chip_state)); +struct iio_dev *indio_dev = iio_device_alloc(sizeof(struct chip_state)); where chip_state is a structure of local state data for this instance of the chip. @@ -78,4 +78,4 @@ be registered afterwards (otherwise the whole parentage of devices gets confused) On remove, iio_device_unregister(indio_dev) will remove the device from -the core, and iio_free_device will clean up. +the core, and iio_device_free will clean up. diff --git a/drivers/staging/iio/Documentation/generic_buffer.c b/drivers/staging/iio/Documentation/generic_buffer.c index 69a05b9..bf55335 100644 --- a/drivers/staging/iio/Documentation/generic_buffer.c +++ b/drivers/staging/iio/Documentation/generic_buffer.c @@ -60,9 +60,9 @@ void print2byte(int input, struct iio_channel_info *info) /* First swap if incorrect endian */ if (info->be) - input = be16toh((uint_16t)input); + input = be16toh((uint16_t)input); else - input = le16toh((uint_16t)input); + input = le16toh((uint16_t)input); /* shift before conversion to avoid sign extension of left aligned data */ diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c index 0d21a27..2227584 100644 --- a/drivers/staging/iio/Documentation/iio_event_monitor.c +++ b/drivers/staging/iio/Documentation/iio_event_monitor.c @@ -27,7 +27,7 @@ #include <fcntl.h> #include <sys/ioctl.h> #include "iio_utils.h" -#include "../events.h" +#include <linux/iio/events.h> static const char * const iio_chan_type_name_spec[] = { [IIO_VOLTAGE] = "voltage", diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 new file mode 100755 index 0000000..470f7ad --- /dev/null +++ b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2583 @@ -0,0 +1,6 @@ +What: /sys/bus/iio/devices/device[n]/in_illuminance0_calibrate +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + This property causes an internal calibration of the als gain trim + value which is later used in calculating illuminance in lux. diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x new file mode 100755 index 0000000..b2798b2 --- /dev/null +++ b/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x @@ -0,0 +1,13 @@ +What: /sys/bus/iio/devices/device[n]/in_illuminance0_calibrate +KernelVersion: 3.3-rc1 +Contact: linux-iio@vger.kernel.org +Description: + Causes an internal calibration of the als gain trim + value which is later used in calculating illuminance in lux. + +What: /sys/bus/iio/devices/device[n]/in_proximity0_calibrate +KernelVersion: 3.3-rc1 +Contact: linux-iio@vger.kernel.org +Description: + Causes a recalculation and adjustment to the + proximity_thresh_rising_value. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio deleted file mode 100644 index 46a995d..0000000 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ /dev/null @@ -1,741 +0,0 @@ -What: /sys/bus/iio/devices/iio:deviceX -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware chip or device accessed by one communication port. - Corresponds to a grouping of sensor channels. X is the IIO - index of the device. - -What: /sys/bus/iio/devices/triggerX -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - An event driven driver of data capture to an in kernel buffer. - May be provided by a device driver that also has an IIO device - based on hardware generated events (e.g. data ready) or - provided by a separate driver for other hardware (e.g. - periodic timer, GPIO or high resolution timer). - Contains trigger type specific elements. These do not - generalize well and hence are not documented in this file. - X is the IIO index of the trigger. - -What: /sys/bus/iio/devices/iio:deviceX/buffer -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Directory of attributes relating to the buffer for the device. - -What: /sys/bus/iio/devices/iio:deviceX/name -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Description of the physical chip / device for device X. - Typically a part number. - -What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency -What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency -What: /sys/bus/iio/devices/triggerX/sampling_frequency -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Some devices have internal clocks. This parameter sets the - resulting sampling frequency. In many devices this - parameter has an effect on input filters etc rather than - simply controlling when the input is sampled. As this - effects datardy triggers, hardware buffers and the sysfs - direct access interfaces, it may be found in any of the - relevant directories. If it effects all of the above - then it is to be found in the base device directory. - -What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency_available -What: /sys/.../iio:deviceX/buffer/sampling_frequency_available -What: /sys/bus/iio/devices/triggerX/sampling_frequency_available -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - When the internal sampling clock can only take a small - discrete set of values, this file lists those available. - -What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent ADC oversampling. Controls the sampling ratio - of the digital filter if available. - -What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio_available -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent values supported by the oversampling filter. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled no bias removal etc) voltage measurement from - channel Y. In special cases where the channel does not - correspond to externally available input one of the named - versions may be used. The number must always be specified and - unique to allow association with event codes. Units after - application of scale and offset are microvolts. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled) differential voltage measurement equivalent to - channel Y - channel Z where these channel numbers apply to the - physically equivalent inputs when non differential readings are - separately available. In differential only parts, then all that - is required is a consistent labeling. Units after application - of scale and offset are microvolts. - -What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - Raw capacitance measurement from channel Y. Units after - application of scale and offset are nanofarads. - -What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - Raw differential capacitance measurement equivalent to - channel Y - channel Z where these channel numbers apply to the - physically equivalent inputs when non differential readings are - separately available. In differential only parts, then all that - is required is a consistent labeling. Units after application - of scale and offset are nanofarads.. - -What: /sys/bus/iio/devices/iio:deviceX/in_temp_raw -What: /sys/bus/iio/devices/iio:deviceX/in_tempX_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_temp_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled no bias removal etc) temperature measurement. - It an axis is specified it generally means that the temperature - sensor is associated with one part of a compound device (e.g. - a gyroscope axis). Units after application of scale and offset - are milli degrees Celsuis. - -What: /sys/bus/iio/devices/iio:deviceX/in_tempX_input -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Scaled temperature measurement in milli degrees Celsius. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Acceleration in direction x, y or z (may be arbitrarily assigned - but should match other such assignments on device). - Has all of the equivalent parameters as per voltageY. Units - after application of scale and offset are m/s^2. - -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Angular velocity about axis x, y or z (may be arbitrarily - assigned) Data converted by application of offset then scale to - radians per second. Has all the equivalent parameters as - per voltageY. Units after application of scale and offset are - radians per second. - -What: /sys/bus/iio/devices/iio:deviceX/in_incli_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_incli_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_incli_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Inclination raw reading about axis x, y or z (may be - arbitrarily assigned). Data converted by application of offset - and scale to Degrees. - -What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_raw -What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_raw -What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_raw -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Magnetic field along axis x, y or z (may be arbitrarily - assigned). Data converted by application of offset - then scale to Gauss. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_peak_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_peak_raw -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_peak_raw -KernelVersion: 2.6.36 -Contact: linux-iio@vger.kernel.org -Description: - Highest value since some reset condition. These - attributes allow access to this and are otherwise - the direct equivalent of the <type>Y[_name]_raw attributes. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_xyz_squared_peak_raw -KernelVersion: 2.6.36 -Contact: linux-iio@vger.kernel.org -Description: - A computed peak value based on the sum squared magnitude of - the underlying value in the specified directions. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_offset -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset -What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset -What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset -What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, offset to be added to <type>[Y]_raw prior - to scaling by <type>[Y]_scale in order to obtain value in the - <type> units as specified in <type>[y]_raw documentation. - Not present if the offset is always 0 or unknown. If Y or - axis <x|y|z> is not present, then the offset applies to all - in channels of <type>. - May be writable if a variable offset can be applied on the - device. Note that this is different to calibbias which - is for devices (or drivers) that apply offsets to compensate - for variation between different instances of the part, typically - adjusted by using some hardware supported calibration procedure. - Calibbias is applied internally, offset is applied in userspace - to the _raw output. - -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_scale -What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_scale -What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale -What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale -What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale -What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - If known for a device, scale to be applied to <type>Y[_name]_raw - post addition of <type>[Y][_name]_offset in order to obtain the - measured value in <type> units as specified in - <type>[Y][_name]_raw documentation.. If shared across all in - channels then Y and <x|y|z> are not present and the value is - called <type>[Y][_name]_scale. The peak modifier means this - value is applied to <type>Y[_name]_peak_raw values. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias -What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration offset. (assumed to fix production - inaccuracies). - -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_voltage_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_accel_z_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale -What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Hardware applied calibration scale factor. (assumed to fix - production inaccuracies). If shared across all channels, - <type>_calibscale is used. - -What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale_available -What: /sys/.../iio:deviceX/in_voltageX_scale_available -What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available -What: /sys/.../iio:deviceX/out_voltageX_scale_available -What: /sys/.../iio:deviceX/in_capacitance_scale_available -KernelVersion: 2.635 -Contact: linux-iio@vger.kernel.org -Description: - If a discrete set of scale values are available, they - are listed in this attribute. - -What: /sys/.../in_accel_filter_low_pass_3db_frequency -What: /sys/.../in_magn_filter_low_pass_3db_frequency -What: /sys/.../in_anglvel_filter_low_pass_3db_frequency -KernelVersion: 3.2 -Contact: linux-iio@vger.kernel.org -Description: - If a known or controllable low pass filter is applied - to the underlying data channel, then this parameter - gives the 3dB frequency of the filter in Hz. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled, no bias etc.) output voltage for - channel Y. The number must always be specified and - unique if the output corresponds to a single channel. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY&Z_raw -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Raw (unscaled, no bias etc.) output voltage for an aggregate of - channel Y, channel Z, etc. This interface is available in cases - where a single output sets the value for multiple channels - simultaneously. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode -What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the output powerdown mode. - DAC output stage is disconnected from the amplifier and - 1kohm_to_gnd: connected to ground via an 1kOhm resistor - 100kohm_to_gnd: connected to ground via an 100kOhm resistor - three_state: left floating - For a list of available output power down options read - outX_powerdown_mode_available. If Y is not present the - mode is shared across all outputs. - -What: /sys/.../iio:deviceX/out_votlageY_powerdown_mode_available -What: /sys/.../iio:deviceX/out_voltage_powerdown_mode_available -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Lists all available output power down modes. - If Y is not present the mode is shared across all outputs. - -What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown -What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - Writing 1 causes output Y to enter the power down mode specified - by the corresponding outY_powerdown_mode. Clearing returns to - normal operation. Y may be suppressed if all outputs are - controlled together. - -What: /sys/bus/iio/devices/iio:deviceX/events -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Configuration of which hardware generated events are passed up - to user-space. - -What: /sys/.../iio:deviceX/events/in_accel_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_x_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_x_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_y_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_y_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_magn_z_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_magn_z_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_thresh_falling_en -What: /sys/.../iio:deviceX/events/in_tempY_thresh_rising_en -What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Event generated when channel passes a threshold in the specified - (_rising|_falling) direction. If the direction is not specified, - then either the device will report an event which ever direction - a single threshold value is passed in (e.g. - <type>[Y][_name]_<raw|input>_thresh_value) or - <type>[Y][_name]_<raw|input>_thresh_rising_value and - <type>[Y][_name]_<raw|input>_thresh_falling_value may take - different values, but the device can only enable both thresholds - or neither. - Note the driver will assume the last p events requested are - to be enabled where p is however many it supports (which may - vary depending on the exact set requested. So if you want to be - sure you have set what you think you have, check the contents of - these attributes after everything is configured. Drivers may - have to buffer any parameters so that they are consistent when - a given event type is enabled a future point (and not those for - whatever event was previously enabled). - -What: /sys/.../iio:deviceX/events/in_accel_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_anglvel_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_x_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_x_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_y_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_y_roc_falling_en -What: /sys/.../iio:deviceX/events/in_magn_z_roc_rising_en -What: /sys/.../iio:deviceX/events/in_magn_z_roc_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_supply_roc_falling_en -What: /sys/.../iio:deviceX/events/in_voltageY_roc_rising_en -What: /sys/.../iio:deviceX/events/in_voltageY_roc_falling_en -What: /sys/.../iio:deviceX/events/in_tempY_roc_rising_en -What: /sys/.../iio:deviceX/events/in_tempY_roc_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Event generated when channel passes a threshold on the rate of - change (1st differential) in the specified (_rising|_falling) - direction. If the direction is not specified, then either the - device will report an event which ever direction a single - threshold value is passed in (e.g. - <type>[Y][_name]_<raw|input>_roc_value) or - <type>[Y][_name]_<raw|input>_roc_rising_value and - <type>[Y][_name]_<raw|input>_roc_falling_value may take - different values, but the device can only enable both rate of - change thresholds or neither. - Note the driver will assume the last p events requested are - to be enabled where p is however many it supports (which may - vary depending on the exact set requested. So if you want to be - sure you have set what you think you have, check the contents of - these attributes after everything is configured. Drivers may - have to buffer any parameters so that they are consistent when - a given event type is enabled a future point (and not those for - whatever event was previously enabled). - -What: /sys/.../events/in_accel_x_raw_thresh_rising_value -What: /sys/.../events/in_accel_x_raw_thresh_falling_value -What: /sys/.../events/in_accel_y_raw_thresh_rising_value -What: /sys/.../events/in_accel_y_raw_thresh_falling_value -What: /sys/.../events/in_accel_z_raw_thresh_rising_value -What: /sys/.../events/in_accel_z_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_x_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_x_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_y_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_y_raw_thresh_falling_value -What: /sys/.../events/in_anglvel_z_raw_thresh_rising_value -What: /sys/.../events/in_anglvel_z_raw_thresh_falling_value -What: /sys/.../events/in_magn_x_raw_thresh_rising_value -What: /sys/.../events/in_magn_x_raw_thresh_falling_value -What: /sys/.../events/in_magn_y_raw_thresh_rising_value -What: /sys/.../events/in_magn_y_raw_thresh_falling_value -What: /sys/.../events/in_magn_z_raw_thresh_rising_value -What: /sys/.../events/in_magn_z_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_supply_raw_thresh_rising_value -What: /sys/.../events/in_voltageY_supply_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_raw_thresh_falling_value -What: /sys/.../events/in_voltageY_raw_thresh_falling_value -What: /sys/.../events/in_tempY_raw_thresh_falling_value -What: /sys/.../events/in_tempY_raw_thresh_falling_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the value of threshold that the device is comparing - against for the events enabled by - <type>Y[_name]_thresh[_rising|falling]_en. - If separate attributes exist for the two directions, but - direction is not specified for this attribute, then a single - threshold value applies to both directions. - The raw or input element of the name indicates whether the - value is in raw device units or in processed units (as _raw - and _input do on sysfs direct channel read attributes). - -What: /sys/.../events/in_accel_x_raw_roc_rising_value -What: /sys/.../events/in_accel_x_raw_roc_falling_value -What: /sys/.../events/in_accel_y_raw_roc_rising_value -What: /sys/.../events/in_accel_y_raw_roc_falling_value -What: /sys/.../events/in_accel_z_raw_roc_rising_value -What: /sys/.../events/in_accel_z_raw_roc_falling_value -What: /sys/.../events/in_anglvel_x_raw_roc_rising_value -What: /sys/.../events/in_anglvel_x_raw_roc_falling_value -What: /sys/.../events/in_anglvel_y_raw_roc_rising_value -What: /sys/.../events/in_anglvel_y_raw_roc_falling_value -What: /sys/.../events/in_anglvel_z_raw_roc_rising_value -What: /sys/.../events/in_anglvel_z_raw_roc_falling_value -What: /sys/.../events/in_magn_x_raw_roc_rising_value -What: /sys/.../events/in_magn_x_raw_roc_falling_value -What: /sys/.../events/in_magn_y_raw_roc_rising_value -What: /sys/.../events/in_magn_y_raw_roc_falling_value -What: /sys/.../events/in_magn_z_raw_roc_rising_value -What: /sys/.../events/in_magn_z_raw_roc_falling_value -What: /sys/.../events/in_voltageY_supply_raw_roc_rising_value -What: /sys/.../events/in_voltageY_supply_raw_roc_falling_value -What: /sys/.../events/in_voltageY_raw_roc_falling_value -What: /sys/.../events/in_voltageY_raw_roc_falling_value -What: /sys/.../events/in_tempY_raw_roc_falling_value -What: /sys/.../events/in_tempY_raw_roc_falling_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Specifies the value of rate of change threshold that the - device is comparing against for the events enabled by - <type>[Y][_name]_roc[_rising|falling]_en. - If separate attributes exist for the two directions, - but direction is not specified for this attribute, - then a single threshold value applies to both directions. - The raw or input element of the name indicates whether the - value is in raw device units or in processed units (as _raw - and _input do on sysfs direct channel read attributes). - -What: /sys/.../events/in_accel_x_thresh_rising_period -What: /sys/.../events/in_accel_x_thresh_falling_period -hat: /sys/.../events/in_accel_x_roc_rising_period -What: /sys/.../events/in_accel_x_roc_falling_period -What: /sys/.../events/in_accel_y_thresh_rising_period -What: /sys/.../events/in_accel_y_thresh_falling_period -What: /sys/.../events/in_accel_y_roc_rising_period -What: /sys/.../events/in_accel_y_roc_falling_period -What: /sys/.../events/in_accel_z_thresh_rising_period -What: /sys/.../events/in_accel_z_thresh_falling_period -What: /sys/.../events/in_accel_z_roc_rising_period -What: /sys/.../events/in_accel_z_roc_falling_period -What: /sys/.../events/in_anglvel_x_thresh_rising_period -What: /sys/.../events/in_anglvel_x_thresh_falling_period -What: /sys/.../events/in_anglvel_x_roc_rising_period -What: /sys/.../events/in_anglvel_x_roc_falling_period -What: /sys/.../events/in_anglvel_y_thresh_rising_period -What: /sys/.../events/in_anglvel_y_thresh_falling_period -What: /sys/.../events/in_anglvel_y_roc_rising_period -What: /sys/.../events/in_anglvel_y_roc_falling_period -What: /sys/.../events/in_anglvel_z_thresh_rising_period -What: /sys/.../events/in_anglvel_z_thresh_falling_period -What: /sys/.../events/in_anglvel_z_roc_rising_period -What: /sys/.../events/in_anglvel_z_roc_falling_period -What: /sys/.../events/in_magn_x_thresh_rising_period -What: /sys/.../events/in_magn_x_thresh_falling_period -What: /sys/.../events/in_magn_x_roc_rising_period -What: /sys/.../events/in_magn_x_roc_falling_period -What: /sys/.../events/in_magn_y_thresh_rising_period -What: /sys/.../events/in_magn_y_thresh_falling_period -What: /sys/.../events/in_magn_y_roc_rising_period -What: /sys/.../events/in_magn_y_roc_falling_period -What: /sys/.../events/in_magn_z_thresh_rising_period -What: /sys/.../events/in_magn_z_thresh_falling_period -What: /sys/.../events/in_magn_z_roc_rising_period -What: /sys/.../events/in_magn_z_roc_falling_period -What: /sys/.../events/in_voltageY_supply_thresh_rising_period -What: /sys/.../events/in_voltageY_supply_thresh_falling_period -What: /sys/.../events/in_voltageY_supply_roc_rising_period -What: /sys/.../events/in_voltageY_supply_roc_falling_period -What: /sys/.../events/in_voltageY_thresh_rising_period -What: /sys/.../events/in_voltageY_thresh_falling_period -What: /sys/.../events/in_voltageY_roc_rising_period -What: /sys/.../events/in_voltageY_roc_falling_period -What: /sys/.../events/in_tempY_thresh_rising_period -What: /sys/.../events/in_tempY_thresh_falling_period -What: /sys/.../events/in_tempY_roc_rising_period -What: /sys/.../events/in_tempY_roc_falling_period -What: /sys/.../events/in_accel_x&y&z_mag_falling_period -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) for which the condition must be - met before an event is generated. If direction is not - specified then this period applies to both directions. - -What: /sys/.../iio:deviceX/events/in_accel_mag_en -What: /sys/.../iio:deviceX/events/in_accel_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_y_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_z_mag_falling_en -What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_rising_en -What: /sys/.../iio:deviceX/events/in_accel_x&y&z_mag_falling_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Similar to in_accel_x_thresh[_rising|_falling]_en, but here the - magnitude of the channel is compared to the threshold, not its - signed value. - -What: /sys/.../events/in_accel_raw_mag_value -What: /sys/.../events/in_accel_x_raw_mag_rising_value -What: /sys/.../events/in_accel_y_raw_mag_rising_value -What: /sys/.../events/in_accel_z_raw_mag_rising_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - The value to which the magnitude of the channel is compared. If - number or direction is not specified, applies to all channels of - this type. - -What: /sys/bus/iio/devices/iio:deviceX/trigger/current_trigger -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - The name of the trigger source being used, as per string given - in /sys/class/iio/triggerY/name. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/length -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Number of scans contained by the buffer. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/bytes_per_datum -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Bytes per scan. Due to alignment fun, the scan may be larger - than implied directly by the scan_element parameters. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/enable -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Actually start the buffer capture up. Will start trigger - if first device and appropriate. - -What: /sys/bus/iio/devices/iio:deviceX/buffer/scan_elements -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Directory containing interfaces for elements that will be - captured for a single triggered sample set in the buffer. - -What: /sys/.../buffer/scan_elements/in_accel_x_en -What: /sys/.../buffer/scan_elements/in_accel_y_en -What: /sys/.../buffer/scan_elements/in_accel_z_en -What: /sys/.../buffer/scan_elements/in_anglvel_x_en -What: /sys/.../buffer/scan_elements/in_anglvel_y_en -What: /sys/.../buffer/scan_elements/in_anglvel_z_en -What: /sys/.../buffer/scan_elements/in_magn_x_en -What: /sys/.../buffer/scan_elements/in_magn_y_en -What: /sys/.../buffer/scan_elements/in_magn_z_en -What: /sys/.../buffer/scan_elements/in_timestamp_en -What: /sys/.../buffer/scan_elements/in_voltageY_supply_en -What: /sys/.../buffer/scan_elements/in_voltageY_en -What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en -What: /sys/.../buffer/scan_elements/in_incli_x_en -What: /sys/.../buffer/scan_elements/in_incli_y_en -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Scan element control for triggered data capture. - -What: /sys/.../buffer/scan_elements/in_accel_type -What: /sys/.../buffer/scan_elements/in_anglvel_type -What: /sys/.../buffer/scan_elements/in_magn_type -What: /sys/.../buffer/scan_elements/in_incli_type -What: /sys/.../buffer/scan_elements/in_voltageY_type -What: /sys/.../buffer/scan_elements/in_voltage-in_type -What: /sys/.../buffer/scan_elements/in_voltageY_supply_type -What: /sys/.../buffer/scan_elements/in_timestamp_type -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Description of the scan element data storage within the buffer - and hence the form in which it is read from user-space. - Form is [be|le]:[s|u]bits/storagebits[>>shift]. - be or le specifies big or little endian. s or u specifies if - signed (2's complement) or unsigned. bits is the number of bits - of data and storagebits is the space (after padding) that it - occupies in the buffer. shift if specified, is the shift that - needs to be applied prior to masking out unused bits. Some - devices put their data in the middle of the transferred elements - with additional information on both sides. Note that some - devices will have additional information in the unused bits - so to get a clean value, the bits value must be used to mask - the buffer output value appropriately. The storagebits value - also specifies the data alignment. So s48/64>>2 will be a - signed 48 bit integer stored in a 64 bit location aligned to - a a64 bit boundary. To obtain the clean value, shift right 2 - and apply a mask to zero the top 16 bits of the result. - For other storage combinations this attribute will be extended - appropriately. - -What: /sys/.../buffer/scan_elements/in_accel_type_available -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - If the type parameter can take one of a small set of values, - this attribute lists them. - -What: /sys/.../buffer/scan_elements/in_voltageY_index -What: /sys/.../buffer/scan_elements/in_voltageY_supply_index -What: /sys/.../buffer/scan_elements/in_accel_x_index -What: /sys/.../buffer/scan_elements/in_accel_y_index -What: /sys/.../buffer/scan_elements/in_accel_z_index -What: /sys/.../buffer/scan_elements/in_anglvel_x_index -What: /sys/.../buffer/scan_elements/in_anglvel_y_index -What: /sys/.../buffer/scan_elements/in_anglvel_z_index -What: /sys/.../buffer/scan_elements/in_magn_x_index -What: /sys/.../buffer/scan_elements/in_magn_y_index -What: /sys/.../buffer/scan_elements/in_magn_z_index -What: /sys/.../buffer/scan_elements/in_incli_x_index -What: /sys/.../buffer/scan_elements/in_incli_y_index -What: /sys/.../buffer/scan_elements/in_timestamp_index -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - A single positive integer specifying the position of this - scan element in the buffer. Note these are not dependent on - what is enabled and may not be contiguous. Thus for user-space - to establish the full layout these must be used in conjunction - with all _en attributes to establish which channels are present, - and the relevant _type attributes to establish the data storage - format. - -What: /sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw -KernelVersion: 2.6.38 -Contact: linux-iio@vger.kernel.org -Description: - This attribute is used to read the amount of quadrature error - present in the device at a given time. - -What: /sys/.../iio:deviceX/ac_excitation_en -KernelVersion: 3.1.0 -Contact: linux-iio@vger.kernel.org -Description: - This attribute, if available, is used to enable the AC - excitation mode found on some converters. In ac excitation mode, - the polarity of the excitation voltage is reversed on - alternate cycles, to eliminate DC errors. - -What: /sys/.../iio:deviceX/bridge_switch_en -KernelVersion: 3.1.0 -Contact: linux-iio@vger.kernel.org -Description: - This attribute, if available, is used to close or open the - bridge power down switch found on some converters. - In bridge applications, such as strain gauges and load cells, - the bridge itself consumes the majority of the current in the - system. To minimize the current consumption of the system, - the bridge can be disconnected (when it is not being used - using the bridge_switch_en attribute. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 b/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 new file mode 100644 index 0000000..1c35c50 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-ad7192 @@ -0,0 +1,20 @@ +What: /sys/.../iio:deviceX/ac_excitation_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to enable the AC + excitation mode found on some converters. In ac excitation mode, + the polarity of the excitation voltage is reversed on + alternate cycles, to eliminate DC errors. + +What: /sys/.../iio:deviceX/bridge_switch_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to close or open the + bridge power down switch found on some converters. + In bridge applications, such as strain gauges and load cells, + the bridge itself consumes the majority of the current in the + system. To minimize the current consumption of the system, + the bridge can be disconnected (when it is not being used + using the bridge_switch_en attribute. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-dds b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds index ffdd547..ee8c509 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-dds +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds @@ -1,83 +1,86 @@ -What: /sys/bus/iio/devices/.../ddsX_freqY +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencyY KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Stores frequency into tuning word Y. - There will be more than one ddsX_freqY file, which allows for - pin controlled FSK Frequency Shift Keying - (ddsX_pincontrol_freq_en is active) or the user can control - the desired active tuning word by writing Y to the - ddsX_freqsymbol file. + There will be more than one out_altvoltageX_frequencyY file, + which allows for pin controlled FSK Frequency Shift Keying + (out_altvoltageX_pincontrol_frequency_en is active) or the user + can control the desired active tuning word by writing Y to the + out_altvoltageX_frequencysymbol file. -What: /sys/bus/iio/devices/.../ddsX_freqY_scale +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencyY_scale KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Scale to be applied to ddsX_freqY in order to obtain the - desired value in Hz. If shared across all frequency registers - Y is not present. It is also possible X is not present if - shared across all channels. + Scale to be applied to out_altvoltageX_frequencyY in order to + obtain the desired value in Hz. If shared across all frequency + registers Y is not present. It is also possible X is not present + if shared across all channels. -What: /sys/bus/iio/devices/.../ddsX_freqsymbol +What: /sys/bus/iio/devices/.../out_altvoltageX_frequencysymbol KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Specifies the active output frequency tuning word. The value - corresponds to the Y in ddsX_freqY. To exit this mode the user - can write ddsX_pincontrol_freq_en or ddsX_out_enable file. + corresponds to the Y in out_altvoltageX_frequencyY. + To exit this mode the user can write + out_altvoltageX_pincontrol_frequency_en or + out_altvoltageX_out_enable file. -What: /sys/bus/iio/devices/.../ddsX_phaseY +What: /sys/bus/iio/devices/.../out_altvoltageX_phaseY KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Stores phase into Y. - There will be more than one ddsX_phaseY file, which allows for - pin controlled PSK Phase Shift Keying - (ddsX_pincontrol_phase_en is active) or the user can + There will be more than one out_altvoltageX_phaseY file, which + allows for pin controlled PSK Phase Shift Keying + (out_altvoltageX_pincontrol_phase_en is active) or the user can control the desired phase Y which is added to the phase - accumulator output by writing Y to the en_phase file. + accumulator output by writing Y to the phase_en file. -What: /sys/bus/iio/devices/.../ddsX_phaseY_scale +What: /sys/bus/iio/devices/.../out_altvoltageX_phaseY_scale KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Scale to be applied to ddsX_phaseY in order to obtain the - desired value in rad. If shared across all phase registers + Scale to be applied to out_altvoltageX_phaseY in order to obtain + the desired value in rad. If shared across all phase registers Y is not present. It is also possible X is not present if shared across all channels. -What: /sys/bus/iio/devices/.../ddsX_phasesymbol +What: /sys/bus/iio/devices/.../out_altvoltageX_phasesymbol KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Specifies the active phase Y which is added to the phase accumulator output. The value corresponds to the Y in - ddsX_phaseY. To exit this mode the user can write - ddsX_pincontrol_phase_en or disable file. + out_altvoltageX_phaseY. To exit this mode the user can write + out_altvoltageX_pincontrol_phase_en or disable file. -What: /sys/bus/iio/devices/.../ddsX_pincontrol_en -What: /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en -What: /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_frequency_en +What: /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_phase_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - ddsX_pincontrol_en: Both, the active frequency and phase is - controlled by the respective phase and frequency control inputs. - In case the device in question allows to independent controls, - then there are dedicated files (ddsX_pincontrol_freq_en, - ddsX_pincontrol_phase_en). + out_altvoltageX_pincontrol_en: Both, the active frequency and + phase is controlled by the respective phase and frequency + control inputs. In case the device in features independent + controls, then there are dedicated files + (out_altvoltageX_pincontrol_frequency_en, + out_altvoltageX_pincontrol_phase_en). -What: /sys/bus/iio/devices/.../ddsX_out_enable -What: /sys/bus/iio/devices/.../ddsX_outY_enable +What: /sys/bus/iio/devices/.../out_altvoltageX_out_enable +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_enable KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - ddsX_outY_enable controls signal generation on output Y of - channel X. Y may be suppressed if all channels are + out_altvoltageX_outY_enable controls signal generation on + output Y of channel X. Y may be suppressed if all channels are controlled together. -What: /sys/bus/iio/devices/.../ddsX_outY_wavetype +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -86,7 +89,7 @@ Description: For a list of available output waveform options read available_output_modes. -What: /sys/bus/iio/devices/.../ddsX_outY_wavetype_available +What: /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light index edbf470..715c74d 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -26,7 +26,7 @@ Description: Hardware dependent list of possible values supported for the adc_resolution of the given sensor. -What: /sys/bus/iio/devices/device[n]/illuminance0[_input|_raw] +What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw] KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -45,7 +45,7 @@ Description: do this calculation manually by reading the infrared sensor value and doing the negation in sw. -What: /sys/bus/iio/devices/device[n]/proximity[_input|_raw] +What: /sys/bus/iio/devices/device[n]/in_proximity[_input|_raw] KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -63,23 +63,22 @@ Description: and if expressed in SI units, should include _input. If this value is not in SI units, then it should include _raw. -What: /sys/bus/iio/devices/device[n]/illuminance0_target +What: /sys/bus/iio/devices/device[n]/in_illuminance0_target KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: This property gets/sets the last known external lux measurement used in/for calibration. -What: /sys/bus/iio/devices/device[n]/illuminance0_integration_time +What: /sys/bus/iio/devices/device[n]/in_illuminance0_integration_time KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: This property gets/sets the sensors ADC analog integration time. -What: /sys/bus/iio/devices/device[n]/illuminance0_calibscale +What: /sys/bus/iio/devices/device[n]/in_illuminance0_lux_table KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Hardware or software applied calibration scale factor assumed - to account for attenuation due to industrial design (glass - filters or aperture holes). + This property gets/sets the table of coefficients + used in calculating illuminance in lux. diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt index fc2012e..75cc37f 100644 --- a/drivers/staging/iio/Documentation/trigger.txt +++ b/drivers/staging/iio/Documentation/trigger.txt @@ -5,7 +5,7 @@ an IIO device. Whilst this can create device specific complexities such triggers are registered with the core in the same way as stand-alone triggers. -struct iio_trig *trig = iio_allocate_trigger("<trigger format string>", ...); +struct iio_trig *trig = iio_trigger_alloc("<trigger format string>", ...); allocates a trigger structure. The key elements to then fill in within a driver are: diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index fe1586718..3c8e5ec 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -1,16 +1,9 @@ # # Industrial I/O subsytem configuration # +menu "IIO staging drivers" + depends on IIO -menuconfig IIO - tristate "Industrial I/O support" - depends on GENERIC_HARDIRQS - help - The industrial I/O subsystem provides a unified framework for - drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - drivers/staging/iio/Documentation for more information. -if IIO config IIO_ST_HWMON tristate "Hwmon driver that uses channels specified via iio maps" depends on HWMON @@ -19,12 +12,6 @@ config IIO_ST_HWMON map allows IIO devices to provide basic hwmon functionality for those channels specified in the map. -config IIO_BUFFER - bool "Enable buffer support within IIO" - help - Provide core support for various buffer based data - acquisition methods. - if IIO_BUFFER config IIO_SW_RING @@ -36,39 +23,14 @@ config IIO_SW_RING with the intention that some devices would be able to write in interrupt context. -config IIO_KFIFO_BUF - select IIO_TRIGGER - tristate "Industrial I/O buffering based on kfifo" - help - A simple fifo based on kfifo. Use this if you want a fifo - rather than a ring buffer. Note that this currently provides - no buffer events so it is up to userspace to work out how - often to read from the buffer. - endif # IIO_BUFFER -config IIO_TRIGGER - boolean "Enable triggered sampling support" - help - Provides IIO core support for triggers. Currently these - are used to initialize capture of samples to push into - ring buffers. The triggers are effectively a 'capture - data now' interrupt. - -config IIO_CONSUMERS_PER_TRIGGER - int "Maximum number of consumers per trigger" - depends on IIO_TRIGGER - default "2" - help - This value controls the maximum number of consumers that a - given trigger may handle. Default is 2. - source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/cdc/Kconfig" source "drivers/staging/iio/dac/Kconfig" -source "drivers/staging/iio/dds/Kconfig" +source "drivers/staging/iio/frequency/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/impedance-analyzer/Kconfig" source "drivers/staging/iio/imu/Kconfig" @@ -104,4 +66,4 @@ config IIO_SIMPLE_DUMMY_BUFFER endif # IIO_SIMPLE_DUMMY -endif # IIO +endmenu diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 5075291..6a46d5a 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -2,13 +2,7 @@ # Makefile for the industrial I/O core. # -obj-$(CONFIG_IIO) += industrialio.o -industrialio-y := industrialio-core.o industrialio-event.o inkern.o -industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o -industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o - obj-$(CONFIG_IIO_SW_RING) += ring_sw.o -obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o iio_dummy-y := iio_simple_dummy.o @@ -24,7 +18,7 @@ obj-y += adc/ obj-y += addac/ obj-y += cdc/ obj-y += dac/ -obj-y += dds/ +obj-y += frequency/ obj-y += gyro/ obj-y += impedance-analyzer/ obj-y += imu/ diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index d1ad35e..cf3f948 100644 --- a/drivers/staging/iio/TODO +++ b/drivers/staging/iio/TODO @@ -67,7 +67,7 @@ e-mailing the normal IIO list (see below). Documentation 1) Lots of cleanup and expansion. -2) Some device require indvidual docs. +2) Some device require individual docs. Contact: Jonathan Cameron <jic23@cam.ac.uk>. Mailing list: linux-iio@vger.kernel.org diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index d439e45..02b3409 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -15,9 +15,9 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16201.h" @@ -171,7 +171,7 @@ static ssize_t adis16201_write_reset(struct device *dev, ret = strtobool(buf, &res); if (ret || !res) return ret; - return adis16201_reset(dev_get_drvdata(dev)); + return adis16201_reset(dev_to_iio_dev(dev)); } int adis16201_set_irq(struct iio_dev *indio_dev, bool enable) @@ -298,7 +298,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16201_addresses[chan->address][0]; ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); @@ -406,39 +406,104 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16201_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16201_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, + .address = in_supply, + .scan_index = ADIS16201_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16201_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, + .address = temp, + .scan_index = ADIS16201_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16201_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, + .address = accel_x, + .scan_index = ADIS16201_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16201_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, + .address = accel_y, + .scan_index = ADIS16201_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16201_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, + .address = in_aux, + .scan_index = ADIS16201_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_x, ADIS16201_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, + .address = incli_x, + .scan_index = ADIS16201_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_y, ADIS16201_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), + .address = incli_y, + .scan_index = ADIS16201_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(7) }; @@ -467,7 +532,7 @@ static int __devinit adis16201_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -522,7 +587,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16201_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -535,7 +600,7 @@ static int adis16201_remove(struct spi_device *spi) adis16201_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16201_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 97f9e6b..247602a 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -5,9 +5,9 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16201.h" @@ -66,9 +66,8 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; @@ -81,7 +80,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c index bce505e..96fdabb 100644 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16201.h" /** @@ -29,7 +29,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16201_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16201-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16201-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -56,7 +56,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -67,5 +67,5 @@ void adis16201_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_free(state->trig); } diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 1a5140f..15d46bf 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -15,9 +15,9 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16203.h" @@ -182,7 +182,7 @@ static ssize_t adis16203_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); if (len < 1) return -EINVAL; switch (buf[0]) { @@ -305,7 +305,7 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, u8 addr; s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16203_addresses[chan->address][0]; ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); @@ -372,29 +372,75 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16203_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16203_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16203_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - incli_x, ADIS16203_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - /* Fixme: Not what it appears to be - see data sheet */ - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_y, ADIS16203_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16203_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16203_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16203_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = incli_x, + .scan_index = ADIS16203_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { /* Fixme: Not what it appears to be - see data sheet */ + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_y, + .scan_index = ADIS16203_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16203_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(5), }; @@ -423,7 +469,7 @@ static int __devinit adis16203_probe(struct spi_device *spi) struct adis16203_state *st; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -477,7 +523,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16203_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -490,7 +536,7 @@ static int adis16203_remove(struct spi_device *spi) adis16203_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16203_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 6a8963d..7bbd2c2 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -5,20 +5,19 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16203.h" /** * adis16203_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read **/ -static int adis16203_read_ring_data(struct device *dev, u8 *rx) +static int adis16203_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16203_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16203_OUTPUTS + 1]; int ret; @@ -66,22 +65,21 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; } if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0) + adis16203_read_ring_data(indio_dev, st->rx) >= 0) for (; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c index 24bcb8e..b8a0407 100644 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16203.h" /** @@ -29,7 +29,7 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16203_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16203-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16203-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -58,7 +58,7 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -69,5 +69,5 @@ void adis16203_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index fa89364..ac9d95e 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -18,9 +18,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16204.h" @@ -173,7 +173,7 @@ static ssize_t adis16204_read_14bit_signed(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); s16 val = 0; ssize_t ret; @@ -211,7 +211,7 @@ static ssize_t adis16204_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); if (len < 1) return -EINVAL; @@ -342,7 +342,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, int addrind; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16204_addresses[chan->address][0]; ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); @@ -444,31 +444,78 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16204_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 0, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16204_SCAN_SUPPLY, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16204_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16204_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - accel_x, ADIS16204_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - accel_y, ADIS16204_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, /* Note was not previously indexed */ + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16204_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16204_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16204_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16204_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16204_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(5), }; @@ -498,7 +545,7 @@ static int __devinit adis16204_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -551,7 +598,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16204_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -564,7 +611,7 @@ static int adis16204_remove(struct spi_device *spi) adis16204_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16204_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 5c8ab73..f73518b 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -5,20 +5,19 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16204.h" /** * adis16204_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read **/ -static int adis16204_read_ring_data(struct device *dev, u8 *rx) +static int adis16204_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16204_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16204_OUTPUTS + 1]; int ret; @@ -63,22 +62,21 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; } if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0) + adis16204_read_ring_data(indio_dev, st->rx) >= 0) for (; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c index 6e542af..408a168 100644 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16204.h" /** @@ -29,7 +29,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16204_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16204-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -58,7 +58,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -69,5 +69,5 @@ void adis16204_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_free(state->trig); } diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index a98715f..f6fd0d3 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -16,9 +16,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16209.h" @@ -157,7 +157,7 @@ static ssize_t adis16209_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); if (len < 1) return -EINVAL; @@ -331,7 +331,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16209_addresses[chan->address][0]; ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); @@ -408,41 +408,114 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16209_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16209_SCAN_SUPPLY, - IIO_ST('u', 14, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - temp, ADIS16209_SCAN_TEMP, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16209_SCAN_ACC_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16209_SCAN_ACC_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_aux, ADIS16209_SCAN_AUX_ADC, - IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_x, ADIS16209_SCAN_INCLI_X, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - incli_y, ADIS16209_SCAN_INCLI_Y, - IIO_ST('s', 14, 16, 0), 0), - IIO_CHAN(IIO_ROT, 0, 1, 0, NULL, 0, IIO_MOD_X, - 0, - rot, ADIS16209_SCAN_ROT, - IIO_ST('s', 14, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16209_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 0, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16209_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16209_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16209_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16209_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 12, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_x, + .scan_index = ADIS16209_SCAN_INCLI_X, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = incli_y, + .scan_index = ADIS16209_SCAN_INCLI_Y, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { + .type = IIO_ROT, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .address = rot, + .scan_index = ADIS16209_SCAN_ROT, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(8) }; @@ -471,7 +544,7 @@ static int __devinit adis16209_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -524,7 +597,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16209_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -539,7 +612,7 @@ static int adis16209_remove(struct spi_device *spi) adis16209_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16209_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 57254b6b..0906075 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -5,20 +5,19 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16209.h" /** * adis16209_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read **/ -static int adis16209_read_ring_data(struct device *dev, u8 *rx) +static int adis16209_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16209_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16209_OUTPUTS + 1]; int ret; @@ -61,25 +60,23 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct adis16209_state *st = iio_priv(indio_dev); struct iio_buffer *ring = indio_dev->buffer; - int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; } if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16209_read_ring_data(&indio_dev->dev, st->rx) >= 0) + adis16209_read_ring_data(indio_dev, st->rx) >= 0) for (; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index c5d82c1..2ad93dc 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16209.h" /** @@ -38,7 +38,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16209_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16209-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16209-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -66,7 +66,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -77,5 +77,5 @@ void adis16209_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 51a852d..6a9ac89 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -15,8 +15,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "adis16220.h" @@ -145,7 +145,7 @@ static ssize_t adis16220_read_16bit(struct device *dev, char *buf) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); ssize_t ret; s16 val = 0; @@ -164,7 +164,7 @@ static ssize_t adis16220_write_16bit(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; u16 val; @@ -208,7 +208,7 @@ static ssize_t adis16220_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool val; int ret; @@ -228,7 +228,7 @@ static ssize_t adis16220_write_capture(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool val; int ret; @@ -393,7 +393,7 @@ static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); return adis16220_capture_buffer_read(indio_dev, buf, off, count, @@ -415,7 +415,7 @@ static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); return adis16220_capture_buffer_read(indio_dev, buf, off, count, @@ -437,7 +437,7 @@ static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); return adis16220_capture_buffer_read(indio_dev, buf, off, count, @@ -507,7 +507,7 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, u8 bits; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: addrind = 0; break; case IIO_CHAN_INFO_OFFSET: @@ -575,11 +575,13 @@ static const struct iio_chan_spec adis16220_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, }, { .type = IIO_ACCEL, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_PEAK_SEPARATE_BIT, .address = accel, @@ -587,20 +589,23 @@ static const struct iio_chan_spec adis16220_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = in_2, } }; @@ -629,7 +634,7 @@ static int __devinit adis16220_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -680,7 +685,7 @@ error_rm_accel_bin: error_unregister_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -695,7 +700,7 @@ static int adis16220_remove(struct spi_device *spi) sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 17f77fe..8b15eae 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -19,9 +19,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16240.h" @@ -154,7 +154,7 @@ static ssize_t adis16240_spi_read_signed(struct device *dev, char *buf, unsigned bits) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret; s16 val = 0; unsigned shift = 16 - bits; @@ -177,7 +177,7 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev, char *buf) { ssize_t ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); @@ -203,7 +203,7 @@ static ssize_t adis16240_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); if (len < 1) return -EINVAL; @@ -365,7 +365,7 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16240_addresses[chan->address][0]; ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); @@ -468,33 +468,88 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, } static struct iio_chan_spec adis16240_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - in_supply, ADIS16240_SCAN_SUPPLY, - IIO_ST('u', 10, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - 0, - in_aux, ADIS16240_SCAN_AUX_ADC, - IIO_ST('u', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_x, ADIS16240_SCAN_ACC_X, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_y, ADIS16240_SCAN_ACC_Y, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - accel_z, ADIS16240_SCAN_ACC_Z, - IIO_ST('s', 10, 16, 0), 0), - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - temp, ADIS16240_SCAN_TEMP, - IIO_ST('u', 10, 16, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = in_supply, + .scan_index = ADIS16240_SCAN_SUPPLY, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .address = in_aux, + .scan_index = ADIS16240_SCAN_AUX_ADC, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_x, + .scan_index = ADIS16240_SCAN_ACC_X, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_y, + .scan_index = ADIS16240_SCAN_ACC_Y, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_ACCEL, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .address = accel_z, + .scan_index = ADIS16240_SCAN_ACC_Z, + .scan_type = { + .sign = 's', + .realbits = 10, + .storagebits = 16, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = temp, + .scan_index = ADIS16240_SCAN_TEMP, + .scan_type = { + .sign = 'u', + .realbits = 10, + .storagebits = 16, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(6) }; @@ -523,7 +578,7 @@ static int __devinit adis16240_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -576,7 +631,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16240_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -592,7 +647,7 @@ static int adis16240_remove(struct spi_device *spi) adis16240_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16240_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 43ba84e..86a2a47 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -5,20 +5,19 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16240.h" /** * adis16240_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read **/ -static int adis16240_read_ring_data(struct device *dev, u8 *rx) +static int adis16240_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16240_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16240_OUTPUTS + 1]; int ret; @@ -61,22 +60,21 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize, GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; } if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16240_read_ring_data(&indio_dev->dev, st->rx) >= 0) + adis16240_read_ring_data(indio_dev, st->rx) >= 0) for (; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index 8e0ce56..fa90a22 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16240.h" /** @@ -38,7 +38,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16240_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("adis16240-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("adis16240-dev%d", indio_dev->id); if (st->trig == NULL) { ret = -ENOMEM; goto error_ret; @@ -67,7 +67,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -78,5 +78,5 @@ void adis16240_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index d13d721..8cf7cd9 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -23,8 +23,8 @@ #include <linux/slab.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define KXSD9_REG_X 0x00 #define KXSD9_REG_Y 0x02 @@ -158,7 +158,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev, struct kxsd9_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = kxsd9_read(indio_dev, chan->address); if (ret < 0) goto error_ret; @@ -181,7 +181,8 @@ error_ret: .type = IIO_ACCEL, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = KXSD9_REG_##axis, \ } @@ -189,6 +190,7 @@ static struct iio_chan_spec kxsd9_channels[] = { KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z), { .type = IIO_VOLTAGE, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .indexed = 1, .address = KXSD9_REG_AUX, } @@ -226,7 +228,7 @@ static int __devinit kxsd9_probe(struct spi_device *spi) struct kxsd9_state *st; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -254,7 +256,7 @@ static int __devinit kxsd9_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -262,7 +264,7 @@ error_ret: static int __devexit kxsd9_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 376da51..9d26348 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -23,10 +23,10 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/buffer.h> #include "lis3l02dq.h" @@ -257,7 +257,7 @@ static int lis3l02dq_read_raw(struct iio_dev *indio_dev, u8 reg; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { @@ -297,7 +297,7 @@ static ssize_t lis3l02dq_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret, len = 0; s8 t; ret = lis3l02dq_spi_read_reg_8(indio_dev, @@ -328,7 +328,7 @@ static ssize_t lis3l02dq_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); unsigned long val; int ret; u8 t; @@ -513,7 +513,8 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) } #define LIS3L02DQ_INFO_MASK \ - (IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT) @@ -521,13 +522,26 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) +#define LIS3L02DQ_CHAN(index, mod) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = LIS3L02DQ_INFO_MASK, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + .event_mask = LIS3L02DQ_EVENT_MASK, \ + } + static struct iio_chan_spec lis3l02dq_channels[] = { - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK, - 0, 0, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK, - 1, 1, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK, - 2, 2, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK), + LIS3L02DQ_CHAN(0, IIO_MOD_X), + LIS3L02DQ_CHAN(1, IIO_MOD_Y), + LIS3L02DQ_CHAN(2, IIO_MOD_Z), IIO_CHAN_SOFT_TIMESTAMP(3) }; @@ -666,7 +680,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) struct lis3l02dq_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof *st); + indio_dev = iio_device_alloc(sizeof *st); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -724,7 +738,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq))) lis3l02dq_remove_trigger(indio_dev); error_free_interrupt: if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) @@ -734,7 +748,7 @@ error_uninitialize_buffer: error_unreg_buffer_funcs: lis3l02dq_unconfigure_buffer(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -789,7 +803,7 @@ static int lis3l02dq_remove(struct spi_device *spi) iio_buffer_unregister(indio_dev); lis3l02dq_unconfigure_buffer(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; } diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 0fc3973..51b00df 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -6,11 +6,11 @@ #include <linux/slab.h> #include <linux/export.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../kfifo_buf.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> #include "lis3l02dq.h" /** @@ -137,9 +137,9 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct iio_buffer *buffer = indio_dev->buffer; int len = 0; - size_t datasize = buffer->access->get_bytes_per_datum(buffer); - char *data = kmalloc(datasize, GFP_KERNEL); + char *data; + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(indio_dev->dev.parent, "memory alloc failed in buffer bh"); @@ -150,7 +150,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) len = lis3l02dq_get_buffer_element(indio_dev, data); /* Guaranteed to be aligned with 8 byte boundary */ - if (buffer->scan_timestamp) + if (indio_dev->scan_timestamp) *(s64 *)(((phys_addr_t)data + len + sizeof(s64) - 1) & ~(sizeof(s64) - 1)) = pf->timestamp; @@ -163,12 +163,11 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) /* Caller responsible for locking as necessary. */ static int -__lis3l02dq_write_data_ready_config(struct device *dev, bool state) +__lis3l02dq_write_data_ready_config(struct iio_dev *indio_dev, bool state) { int ret; u8 valold; bool currentlyset; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct lis3l02dq_state *st = iio_priv(indio_dev); /* Get the current event mask register */ @@ -236,7 +235,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, int ret = 0; u8 t; - __lis3l02dq_write_data_ready_config(&indio_dev->dev, state); + __lis3l02dq_write_data_ready_config(indio_dev, state); if (state == false) { /* * A possible quirk with the handler is currently worked around @@ -286,7 +285,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) int ret; struct lis3l02dq_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id); + st->trig = iio_trigger_alloc("lis3l02dq-dev%d", indio_dev->id); if (!st->trig) { ret = -ENOMEM; goto error_ret; @@ -302,7 +301,7 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) return 0; error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -312,7 +311,7 @@ void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) struct lis3l02dq_state *st = iio_priv(indio_dev); iio_trigger_unregister(st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 49764fb..6ec5c20 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -18,10 +18,10 @@ #include <linux/spi/spi.h> #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/buffer.h> #include "sca3000.h" @@ -241,7 +241,7 @@ error_ret: static int sca3000_check_status(struct device *dev) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); @@ -268,7 +268,7 @@ static ssize_t sca3000_show_rev(struct device *dev, char *buf) { int len = 0, ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); @@ -296,7 +296,7 @@ sca3000_show_available_measurement_modes(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int len = 0; @@ -328,7 +328,7 @@ sca3000_show_measurement_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int len = 0, ret; @@ -379,7 +379,7 @@ sca3000_store_measurement_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int ret; u8 mask = 0x03; @@ -429,17 +429,31 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); #define SCA3000_INFO_MASK \ - IIO_CHAN_INFO_SCALE_SHARED_BIT + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT #define SCA3000_EVENT_MASK \ (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING)) +#define SCA3000_CHAN(index, mod) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = SCA3000_INFO_MASK, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 11, \ + .storagebits = 16, \ + .shift = 5, \ + }, \ + .event_mask = SCA3000_EVENT_MASK, \ + } + static struct iio_chan_spec sca3000_channels[] = { - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK, - 0, 0, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK, - 1, 1, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), - IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK, - 2, 2, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), + SCA3000_CHAN(0, IIO_MOD_X), + SCA3000_CHAN(1, IIO_MOD_Y), + SCA3000_CHAN(2, IIO_MOD_Z), }; static u8 sca3000_addresses[3][3] = { @@ -462,7 +476,7 @@ static int sca3000_read_raw(struct iio_dev *indio_dev, u8 address; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&st->lock); if (st->mo_det_use_count) { mutex_unlock(&st->lock); @@ -503,7 +517,7 @@ static ssize_t sca3000_read_av_freq(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int len = 0, ret, val; @@ -574,7 +588,7 @@ static ssize_t sca3000_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int ret, len = 0, base_freq = 0, val; @@ -616,7 +630,7 @@ static ssize_t sca3000_set_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int ret, base_freq = 0; int ctrlval; @@ -676,7 +690,7 @@ static ssize_t sca3000_read_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int ret; int val; @@ -897,7 +911,7 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev, char *buf) { int ret, len; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); int val; @@ -925,7 +939,7 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); long val; int ret; @@ -1131,7 +1145,7 @@ static int __devinit sca3000_probe(struct spi_device *spi) struct sca3000_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -1195,7 +1209,7 @@ error_unregister_ring: error_unregister_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -1233,7 +1247,7 @@ static int sca3000_remove(struct spi_device *spi) iio_device_unregister(indio_dev); iio_buffer_unregister(indio_dev); sca3000_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 6b824a1..b7e1a002 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -18,9 +18,9 @@ #include <linux/sched.h> #include <linux/poll.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "../ring_hw.h" #include "sca3000.h" @@ -157,7 +157,7 @@ static ssize_t sca3000_query_ring_int(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret, val; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); @@ -178,7 +178,7 @@ static ssize_t sca3000_set_ring_int(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; @@ -219,7 +219,7 @@ static ssize_t sca3000_show_buffer_scale(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct sca3000_state *st = iio_priv(indio_dev); return sprintf(buf, "0.%06d\n", 4*st->info->scale); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 592eabd..2490dd2 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -25,7 +25,7 @@ config AD7606 depends on GPIOLIB select IIO_BUFFER select IIO_TRIGGER - select IIO_SW_RING + select IIO_KFIFO_BUF help Say yes here to build support for Analog Devices: ad7606, ad7606-6, ad7606-4 analog to digital converters (ADC). @@ -63,7 +63,7 @@ config AD799X_RING_BUFFER bool "Analog Devices AD799x: use ring buffer" depends on AD799X select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF help Say yes here to include ring buffer support in the AD799X ADC driver. @@ -72,7 +72,7 @@ config AD7476 tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -87,7 +87,7 @@ config AD7887 tristate "Analog Devices AD7887 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -113,7 +113,7 @@ config AD7793 tristate "Analog Devices AD7792 AD7793 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices @@ -135,7 +135,7 @@ config AD7192 tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" depends on SPI select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF select IIO_TRIGGER help Say yes here to build support for Analog Devices AD7190, @@ -195,11 +195,20 @@ config MAX1363_RING_BUFFER config LPC32XX_ADC tristate "NXP LPC32XX ADC" - depends on ARCH_LPC32XX && !TOUCHSCREEN_LPC32XX + depends on ARCH_LPC32XX help Say yes here to build support for the integrated ADC inside the LPC32XX SoC. Note that this feature uses the same hardware as the - touchscreen driver, so you can only select one of the two drivers - (lpc32xx_adc or lpc32xx_ts). Provides direct access via sysfs. + touchscreen driver, so you should either select only one of the two + drivers (lpc32xx_adc or lpc32xx_ts) or, in the OpenFirmware case, + activate only one via device tree selection. Provides direct access + via sysfs. + +config SPEAR_ADC + tristate "ST SPEAr ADC" + depends on PLAT_SPEAR + help + Say yes here to build support for the integrated ADC inside the + ST SPEAr SoC. Provides direct access via sysfs. endmenu diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index f83ab95..14e98b6 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -38,3 +38,4 @@ obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o +obj-$(CONFIG_SPEAR_ADC) += spear_adc.o diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 9fd6d63..5eaeaf1 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -1,7 +1,7 @@ /* * AD7190 AD7192 AD7195 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -17,12 +17,12 @@ #include <linux/sched.h> #include <linux/delay.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> #include "ad7192.h" @@ -456,31 +456,19 @@ out: static int ad7192_ring_preenable(struct iio_dev *indio_dev) { struct ad7192_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - indio_dev->channels[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(AD7192_MODE_CONT); st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | @@ -533,7 +521,7 @@ static irqreturn_t ad7192_trigger_handler(int irq, void *p) indio_dev->channels[0].scan_type.realbits/8); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); @@ -556,7 +544,7 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -569,7 +557,7 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -579,8 +567,8 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -588,7 +576,7 @@ error_ret: static void ad7192_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } /** @@ -616,7 +604,7 @@ static int ad7192_probe_trigger(struct iio_dev *indio_dev) struct ad7192_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->spi)->name, indio_dev->id); if (st->trig == NULL) { @@ -649,7 +637,7 @@ static int ad7192_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->spi->irq, indio_dev); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -660,14 +648,14 @@ static void ad7192_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->spi->irq, indio_dev); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } static ssize_t ad7192_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->mclk / @@ -679,7 +667,7 @@ static ssize_t ad7192_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); unsigned long lval; int div, ret; @@ -718,7 +706,7 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, static ssize_t ad7192_show_scale_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); int i, len = 0; @@ -742,7 +730,7 @@ static ssize_t ad7192_show_ac_excitation(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX)); @@ -752,7 +740,7 @@ static ssize_t ad7192_show_bridge_switch(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", !!(st->gpocon & AD7192_GPOCON_BPDSW)); @@ -763,7 +751,7 @@ static ssize_t ad7192_set(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7192_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -849,7 +837,7 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -981,7 +969,8 @@ static const struct iio_info ad7195_info = { .extend_name = _name, \ .channel = _chan, \ .channel2 = _chan2, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} @@ -990,7 +979,8 @@ static const struct iio_info ad7195_info = { { .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} @@ -999,7 +989,8 @@ static const struct iio_info ad7195_info = { { .type = IIO_TEMP, \ .indexed = 1, \ .channel = _chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = _address, \ .scan_index = _si, \ .scan_type = IIO_ST('s', 24, 32, 0)} @@ -1033,7 +1024,7 @@ static int __devinit ad7192_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -1114,7 +1105,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 7dbd681..cfc39a7 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -16,9 +16,9 @@ #include <linux/interrupt.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include "ad7280a.h" @@ -384,7 +384,7 @@ static ssize_t ad7280_show_balance_sw(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -398,7 +398,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); bool readin; @@ -429,7 +429,7 @@ static ssize_t ad7280_show_balance_timer(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -453,7 +453,7 @@ static ssize_t ad7280_store_balance_timer(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned long val; @@ -508,6 +508,7 @@ static int ad7280_channel_init(struct ad7280_state *st) } st->channels[cnt].indexed = 1; st->channels[cnt].info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT; st->channels[cnt].address = AD7280A_DEVADDR(dev) << 8 | ch; @@ -524,7 +525,9 @@ static int ad7280_channel_init(struct ad7280_state *st) st->channels[cnt].channel2 = dev * 6; st->channels[cnt].address = AD7280A_ALL_CELLS; st->channels[cnt].indexed = 1; - st->channels[cnt].info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT; + st->channels[cnt].info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT; st->channels[cnt].scan_index = cnt; st->channels[cnt].scan_type.sign = 'u'; st->channels[cnt].scan_type.realbits = 32; @@ -596,7 +599,7 @@ static ssize_t ad7280_read_channel_config(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned val; @@ -626,7 +629,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7280_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -788,7 +791,7 @@ static int ad7280_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (chan->address == AD7280A_ALL_CELLS) ret = ad7280_read_all_channels(st, st->scan_cnt, NULL); @@ -836,7 +839,7 @@ static int __devinit ad7280_probe(struct spi_device *spi) int ret; const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890}; const unsigned short nAVG[4] = {1, 2, 4, 8}; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -942,7 +945,7 @@ error_free_channels: kfree(st->channels); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -961,7 +964,7 @@ static int __devexit ad7280_remove(struct spi_device *spi) kfree(st->channels); kfree(st->iio_attr); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 81d6b61..029b39c 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -17,9 +17,9 @@ #include <linux/regulator/consumer.h> #include <linux/err.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> /* * Simplified handling @@ -132,7 +132,7 @@ static ssize_t ad7291_store_reset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7291_chip_info *chip = iio_priv(indio_dev); return ad7291_i2c_write(chip, AD7291_COMMAND, @@ -214,7 +214,7 @@ static inline ssize_t ad7291_show_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7291_chip_info *chip = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u16 data; @@ -232,7 +232,7 @@ static inline ssize_t ad7291_set_hyst(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7291_chip_info *chip = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u16 data; @@ -461,7 +461,7 @@ static int ad7291_read_raw(struct iio_dev *indio_dev, s16 signval; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_VOLTAGE: mutex_lock(&chip->state_lock); @@ -536,7 +536,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev, #define AD7291_VOLTAGE_CHAN(_chan) \ { \ .type = IIO_VOLTAGE, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .indexed = 1, \ .channel = _chan, \ .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\ @@ -554,7 +555,8 @@ static const struct iio_chan_spec ad7291_channels[] = { AD7291_VOLTAGE_CHAN(7), { .type = IIO_TEMP, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .indexed = 1, .channel = 0, @@ -585,7 +587,7 @@ static int __devinit ad7291_probe(struct i2c_client *client, struct iio_dev *indio_dev; int ret = 0, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -667,7 +669,7 @@ error_put_reg: if (!IS_ERR(chip->reg)) regulator_put(chip->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -687,7 +689,7 @@ static int __devexit ad7291_remove(struct i2c_client *client) regulator_put(chip->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index a0e5dea..5051a7e 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -38,7 +38,6 @@ struct ad7298_platform_data { struct ad7298_state { struct spi_device *spi; struct regulator *reg; - size_t d_size; u16 int_vref_mv; unsigned ext_ref; struct spi_transfer ring_xfer[10]; diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 8dd6aa9..c90f2b3 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -16,40 +16,51 @@ #include <linux/delay.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "ad7298.h" +#define AD7298_V_CHAN(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + } + static struct iio_chan_spec ad7298_channels[] = { - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 1, 1, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 2, 2, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 3, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 3, 3, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 4, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 4, 4, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 5, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 5, 5, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 6, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 6, 6, IIO_ST('u', 12, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 7, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 7, 7, IIO_ST('u', 12, 16, 0), 0), + { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = 9, + .scan_index = AD7298_CH_TEMP, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + }, + }, + AD7298_V_CHAN(0), + AD7298_V_CHAN(1), + AD7298_V_CHAN(2), + AD7298_V_CHAN(3), + AD7298_V_CHAN(4), + AD7298_V_CHAN(5), + AD7298_V_CHAN(6), + AD7298_V_CHAN(7), IIO_CHAN_SOFT_TIMESTAMP(8), }; @@ -121,7 +132,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { ret = -EBUSY; @@ -168,7 +179,7 @@ static int __devinit ad7298_probe(struct spi_device *spi) struct ad7298_platform_data *pdata = spi->dev.platform_data; struct ad7298_state *st; int ret; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -241,7 +252,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -258,7 +269,7 @@ static int __devexit ad7298_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index feeb0ee..908a3e5 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -1,7 +1,7 @@ /* * AD7298 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -11,10 +11,10 @@ #include <linux/slab.h> #include <linux/spi/spi.h> -#include "../iio.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> #include "ad7298.h" @@ -28,25 +28,17 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) { struct ad7298_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; int i, m; unsigned short command; - int scan_count = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); - d_size = scan_count * (AD7298_STORAGE_BITS / 8); - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } + int scan_count, ret; - if (ring->access->set_bytes_per_datum) - ring->access->set_bytes_per_datum(ring, d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; - st->d_size = d_size; + /* Now compute overall size */ + scan_count = bitmap_weight(indio_dev->active_scan_mask, + indio_dev->masklength); command = AD7298_WRITE | st->ext_ref; @@ -100,9 +92,9 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) if (b_sent) return b_sent; - if (ring->scan_timestamp) { + if (indio_dev->scan_timestamp) { time_ns = iio_get_time_ns(); - memcpy((u8 *)buf + st->d_size - sizeof(s64), + memcpy((u8 *)buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); } @@ -126,7 +118,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -140,7 +132,7 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -151,8 +143,8 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -160,5 +152,5 @@ error_ret: void ad7298_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index 27f696c..b1dd931 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -27,7 +27,6 @@ struct ad7476_state { struct spi_device *spi; const struct ad7476_chip_info *chip_info; struct regulator *reg; - size_t d_size; u16 int_vref_mv; struct spi_transfer xfer; struct spi_message msg; diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 0c064d1..be1c260 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -15,9 +15,9 @@ #include <linux/err.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "ad7476.h" @@ -43,7 +43,7 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -66,53 +66,51 @@ static int ad7476_read_raw(struct iio_dev *indio_dev, return -EINVAL; } +#define AD7476_CHAN(bits) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = 16, \ + .shift = 12 - bits, \ + }, \ +} + static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { [ID_AD7466] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7467] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 10, 16, 2), 0), + .channel[0] = AD7476_CHAN(10), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7468] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1 , 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 8, 16, 4), 0), + .channel[0] = AD7476_CHAN(8), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7475] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7476] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7477] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 10, 16, 2), 0), + .channel[0] = AD7476_CHAN(10), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7478] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 8, 16, 4), 0), + .channel[0] = AD7476_CHAN(8), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), }, [ID_AD7495] = { - .channel[0] = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('u', 12, 16, 0), 0), + .channel[0] = AD7476_CHAN(12), .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), .int_vref_mv = 2500, }, @@ -130,7 +128,7 @@ static int __devinit ad7476_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -200,7 +198,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -218,7 +216,7 @@ static int ad7476_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index d6af6c0..383611b 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Analog Devices Inc. + * Copyright 2010-2012 Analog Devices Inc. * Copyright (C) 2008 Jonathan Cameron * * Licensed under the GPL-2 or later. @@ -13,43 +13,13 @@ #include <linux/slab.h> #include <linux/spi/spi.h> -#include "../iio.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> #include "ad7476.h" -/** - * ad7476_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the number of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. - **/ -static int ad7476_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7476_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); - - return 0; -} - static irqreturn_t ad7476_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -59,7 +29,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) __u8 *rxbuf; int b_sent; - rxbuf = kzalloc(st->d_size, GFP_KERNEL); + rxbuf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (rxbuf == NULL) return -ENOMEM; @@ -70,8 +40,8 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (indio_dev->buffer->scan_timestamp) - memcpy(rxbuf + st->d_size - sizeof(s64), + if (indio_dev->scan_timestamp) + memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns); @@ -83,7 +53,7 @@ done: } static const struct iio_buffer_setup_ops ad7476_ring_setup_ops = { - .preenable = &ad7476_ring_preenable, + .preenable = &iio_sw_buffer_preenable, .postenable = &iio_triggered_buffer_postenable, .predisable = &iio_triggered_buffer_predisable, }; @@ -93,7 +63,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) struct ad7476_state *st = iio_priv(indio_dev); int ret = 0; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -108,7 +78,7 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -119,8 +89,8 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -128,5 +98,5 @@ error_ret: void ad7476_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 97e8d3d..10ab6dc 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -18,9 +18,9 @@ #include <linux/sched.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "ad7606.h" @@ -88,7 +88,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -113,7 +113,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, static ssize_t ad7606_show_range(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); return sprintf(buf, "%u\n", st->range); @@ -122,7 +122,7 @@ static ssize_t ad7606_show_range(struct device *dev, static ssize_t ad7606_store_range(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); unsigned long lval; @@ -147,7 +147,7 @@ static IIO_CONST_ATTR(in_voltage_range_available, "5000 10000"); static ssize_t ad7606_show_oversampling_ratio(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); return sprintf(buf, "%u\n", st->oversampling); @@ -168,7 +168,7 @@ static int ad7606_oversampling_get_index(unsigned val) static ssize_t ad7606_store_oversampling_ratio(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); unsigned long lval; int ret; @@ -229,14 +229,15 @@ static const struct attribute_group ad7606_attribute_group_range = { .attrs = ad7606_attributes_range, }; -#define AD7606_CHANNEL(num) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .address = num, \ - .scan_index = num, \ - .scan_type = IIO_ST('s', 16, 16, 0), \ +#define AD7606_CHANNEL(num) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .address = num, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .scan_index = num, \ + .scan_type = IIO_ST('s', 16, 16, 0), \ } static struct iio_chan_spec ad7606_8_channels[] = { @@ -460,7 +461,7 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq, struct ad7606_platform_data *pdata = dev->platform_data; struct ad7606_state *st; int ret; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; @@ -559,7 +560,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ERR_PTR(ret); } @@ -579,7 +580,7 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq) } ad7606_free_gpios(st); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7606_par.c b/drivers/staging/iio/adc/ad7606_par.c index bb152a8..a53faaf 100644 --- a/drivers/staging/iio/adc/ad7606_par.c +++ b/drivers/staging/iio/adc/ad7606_par.c @@ -12,7 +12,7 @@ #include <linux/err.h> #include <linux/io.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "ad7606.h" static int ad7606_par16_read_block(struct device *dev, diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index 1ef9fbc..24ce8fc 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. * @@ -11,10 +11,10 @@ #include <linux/kernel.h> #include <linux/slab.h> -#include "../iio.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> #include "ad7606.h" @@ -51,8 +51,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) __u8 *buf; int ret; - buf = kzalloc(ring->access->get_bytes_per_datum(ring), - GFP_KERNEL); + buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (buf == NULL) return; @@ -82,9 +81,8 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) time_ns = iio_get_time_ns(); - if (ring->scan_timestamp) - *((s64 *)(buf + ring->access->get_bytes_per_datum(ring) - - sizeof(s64))) = time_ns; + if (indio_dev->scan_timestamp) + *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; ring->access->store_to(indio_dev->buffer, buf, time_ns); done: @@ -104,7 +102,7 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) struct ad7606_state *st = iio_priv(indio_dev); int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -119,13 +117,13 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &ad7606_ring_setup_ops; - indio_dev->buffer->scan_timestamp = true ; + indio_dev->buffer->scan_timestamp = true; INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring); @@ -133,8 +131,8 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -142,5 +140,5 @@ error_ret: void ad7606_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad7606_spi.c b/drivers/staging/iio/adc/ad7606_spi.c index 237f1c4..099d347 100644 --- a/drivers/staging/iio/adc/ad7606_spi.c +++ b/drivers/staging/iio/adc/ad7606_spi.c @@ -11,7 +11,7 @@ #include <linux/types.h> #include <linux/err.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "ad7606.h" #define MAX_SPI_FREQ_HZ 23500000 /* VDRIVE above 4.75 V */ diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index a13e58c..1ece2ac 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -18,8 +18,8 @@ #include <linux/gpio.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "ad7780.h" @@ -94,7 +94,7 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, unsigned long scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = ad7780_read(st, &smpl); mutex_unlock(&indio_dev->mlock); @@ -126,14 +126,34 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { [ID_AD7780] = { - .channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('s', 24, 32, 8), 0), + .channel = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + .shift = 8, + }, + }, }, [ID_AD7781] = { - .channel = IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - 0, 0, IIO_ST('s', 20, 32, 12), 0), + .channel = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .scan_type = { + .sign = 's', + .realbits = 20, + .storagebits = 32, + .shift = 12, + }, + }, }, }; @@ -167,7 +187,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -245,7 +265,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -262,7 +282,7 @@ static int ad7780_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 84ecde1..b36556f 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -1,7 +1,7 @@ /* * AD7792/AD7793 SPI ADC driver * - * Copyright 2011 Analog Devices Inc. + * Copyright 2011-2012 Analog Devices Inc. * * Licensed under the GPL-2. */ @@ -18,12 +18,12 @@ #include <linux/delay.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger.h> +#include <linux/iio/trigger_consumer.h> #include "ad7793.h" @@ -319,31 +319,18 @@ out: static int ad7793_ring_preenable(struct iio_dev *indio_dev) { struct ad7793_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - indio_dev->channels[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(AD7793_MODE_CONT); st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | @@ -399,7 +386,7 @@ static irqreturn_t ad7793_trigger_handler(int irq, void *p) indio_dev->channels[0].scan_type.realbits/8); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); @@ -422,7 +409,7 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -435,7 +422,7 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -445,8 +432,8 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -454,7 +441,7 @@ error_ret: static void ad7793_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } /** @@ -482,7 +469,7 @@ static int ad7793_probe_trigger(struct iio_dev *indio_dev) struct ad7793_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->spi)->name, indio_dev->id); if (st->trig == NULL) { @@ -516,7 +503,7 @@ static int ad7793_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->spi->irq, indio_dev); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -527,7 +514,7 @@ static void ad7793_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->spi->irq, indio_dev); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, @@ -537,7 +524,7 @@ static ssize_t ad7793_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7793_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", @@ -549,7 +536,7 @@ static ssize_t ad7793_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7793_state *st = iio_priv(indio_dev); long lval; int i, ret; @@ -591,7 +578,7 @@ static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( static ssize_t ad7793_show_scale_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7793_state *st = iio_priv(indio_dev); int i, len = 0; @@ -630,7 +617,7 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -760,7 +747,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 0, .channel2 = 0, .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 0, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -771,7 +759,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 1, .channel2 = 1, .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 1, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -782,7 +771,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -794,7 +784,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 24, 32, 0) }, @@ -803,7 +794,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 0, .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('s', 24, 32, 0), }, @@ -813,7 +805,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 4, .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('s', 24, 32, 0), }, @@ -827,7 +820,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 0, .channel2 = 0, .address = AD7793_CH_AIN1P_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 0, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -838,7 +832,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 1, .channel2 = 1, .address = AD7793_CH_AIN2P_AIN2M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 1, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -849,7 +844,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN3P_AIN3M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -861,7 +857,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .channel = 2, .channel2 = 2, .address = AD7793_CH_AIN1M_AIN1M, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = 2, .scan_type = IIO_ST('s', 16, 32, 0) }, @@ -870,7 +867,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 0, .address = AD7793_CH_TEMP, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('s', 16, 32, 0), }, @@ -880,7 +878,8 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { .indexed = 1, .channel = 4, .address = AD7793_CH_AVDD_MONITOR, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('s', 16, 32, 0), }, @@ -905,7 +904,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) return -ENODEV; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -989,7 +988,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -1009,7 +1008,7 @@ static int ad7793_remove(struct spi_device *spi) regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 52b720e..5356b09 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -16,9 +16,9 @@ #include <linux/spi/spi.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> /* * AD7816 config masks @@ -113,7 +113,7 @@ static ssize_t ad7816_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); if (chip->mode) @@ -127,7 +127,7 @@ static ssize_t ad7816_store_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); if (strcmp(buf, "full")) { @@ -159,7 +159,7 @@ static ssize_t ad7816_show_channel(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->channel_id); @@ -170,7 +170,7 @@ static ssize_t ad7816_store_channel(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); unsigned long data; int ret; @@ -208,7 +208,7 @@ static ssize_t ad7816_show_value(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); u16 data; s8 value; @@ -263,7 +263,7 @@ static ssize_t ad7816_show_oti(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); int value; @@ -284,7 +284,7 @@ static inline ssize_t ad7816_set_oti(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7816_chip_info *chip = iio_priv(indio_dev); long value; u8 data; @@ -354,7 +354,7 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) return -EINVAL; } - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -426,7 +426,7 @@ error_free_gpio_convert: error_free_gpio_rdwr: gpio_free(chip->rdwr_pin); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -443,7 +443,7 @@ static int __devexit ad7816_remove(struct spi_device *spi_dev) gpio_free(chip->busy_pin); gpio_free(chip->convert_pin); gpio_free(chip->rdwr_pin); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index bc53b65..2e09e54 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -63,7 +63,6 @@ struct ad7887_state { struct spi_device *spi; const struct ad7887_chip_info *chip_info; struct regulator *reg; - size_t d_size; u16 int_vref_mv; struct spi_transfer xfer[4]; struct spi_message msg[3]; diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index e9bbc3e..7186074 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -15,9 +15,9 @@ #include <linux/err.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "ad7887.h" @@ -42,7 +42,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -75,7 +75,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = 1, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), @@ -84,7 +85,8 @@ static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = 0, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), @@ -104,7 +106,7 @@ static int __devinit ad7887_probe(struct spi_device *spi) struct ad7887_platform_data *pdata = spi->dev.platform_data; struct ad7887_state *st; int ret, voltage_uv = 0; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -220,7 +222,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -237,7 +239,7 @@ static int ad7887_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index d180907..fd91384 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Analog Devices Inc. + * Copyright 2010-2012 Analog Devices Inc. * Copyright (C) 2008 Jonathan Cameron * * Licensed under the GPL-2. @@ -12,10 +12,10 @@ #include <linux/slab.h> #include <linux/spi/spi.h> -#include "../iio.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> #include "ad7887.h" @@ -29,22 +29,11 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) { struct ad7887_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } + int ret; - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; /* We know this is a single long so can 'cheat' */ switch (*indio_dev->active_scan_mask) { @@ -83,7 +72,6 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ad7887_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; s64 time_ns; __u8 *buf; int b_sent; @@ -92,7 +80,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) indio_dev->masklength) * st->chip_info->channel[0].scan_type.storagebits / 8; - buf = kzalloc(st->d_size, GFP_KERNEL); + buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (buf == NULL) return -ENOMEM; @@ -103,8 +91,8 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); memcpy(buf, st->data, bytes); - if (ring->scan_timestamp) - memcpy(buf + st->d_size - sizeof(s64), + if (indio_dev->scan_timestamp) + memcpy(buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); indio_dev->buffer->access->store_to(indio_dev->buffer, buf, time_ns); @@ -126,7 +114,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -139,7 +127,7 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ indio_dev->setup_ops = &ad7887_ring_setup_ops; @@ -148,8 +136,8 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -157,5 +145,5 @@ error_ret: void ad7887_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/ad799x.h b/drivers/staging/iio/adc/ad799x.h index 356f690..99f8abe 100644 --- a/drivers/staging/iio/adc/ad799x.h +++ b/drivers/staging/iio/adc/ad799x.h @@ -104,7 +104,6 @@ struct ad799x_chip_info { struct ad799x_state { struct i2c_client *client; const struct ad799x_chip_info *chip_info; - size_t d_size; struct iio_trigger *trig; struct regulator *reg; u16 int_vref_mv; diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index a845866..80e0c6e 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -33,10 +33,10 @@ #include <linux/err.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/buffer.h> #include "ad799x.h" @@ -148,7 +148,7 @@ static int ad799x_read_raw(struct iio_dev *indio_dev, unsigned int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; @@ -182,7 +182,7 @@ static ssize_t ad799x_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad799x_state *st = iio_priv(indio_dev); int ret; @@ -201,7 +201,7 @@ static ssize_t ad799x_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad799x_state *st = iio_priv(indio_dev); long val; @@ -294,7 +294,7 @@ static ssize_t ad799x_read_channel_config(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad799x_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -312,7 +312,7 @@ static ssize_t ad799x_write_channel_config(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad799x_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -454,6 +454,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -461,6 +462,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -468,6 +470,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -475,6 +478,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -490,6 +494,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -497,6 +502,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -504,6 +510,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -511,6 +518,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -526,6 +534,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -533,6 +542,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -540,6 +550,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -547,6 +558,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 8, 16, 4), }, @@ -562,6 +574,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -570,6 +583,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -587,6 +601,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -596,6 +611,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .indexed = 1, .channel = 1, .scan_index = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, }, @@ -603,6 +619,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -611,6 +628,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -628,6 +646,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -636,6 +655,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -644,6 +664,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -652,6 +673,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -669,6 +691,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -677,6 +700,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -685,6 +709,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -693,6 +718,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 10, 16, 2), .event_mask = AD799X_EV_MASK, @@ -701,6 +727,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -708,6 +735,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -715,6 +743,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 6, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -722,6 +751,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 7, .scan_type = IIO_ST('u', 10, 16, 2), }, @@ -738,6 +768,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 0, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -746,6 +777,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 1, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -754,6 +786,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 2, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 2, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -762,6 +795,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 3, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 3, .scan_type = IIO_ST('u', 12, 16, 0), .event_mask = AD799X_EV_MASK, @@ -770,6 +804,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 4, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 4, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -777,6 +812,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 5, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 5, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -784,6 +820,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 6, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 6, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -791,6 +828,7 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 7, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .scan_index = 7, .scan_type = IIO_ST('u', 12, 16, 0), }, @@ -809,7 +847,7 @@ static int __devinit ad799x_probe(struct i2c_client *client, int ret; struct ad799x_platform_data *pdata = client->dev.platform_data; struct ad799x_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -882,7 +920,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -902,7 +940,7 @@ static __devexit int ad799x_remove(struct i2c_client *client) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 069765c..1c7ff44 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * Copyright (C) 2010-2012 Michael Hennerich, Analog Devices Inc. * Copyright (C) 2008-2010 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify @@ -16,10 +16,10 @@ #include <linux/i2c.h> #include <linux/bitops.h> -#include "../iio.h" -#include "../buffer.h" -#include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> +#include <linux/iio/kfifo_buf.h> +#include <linux/iio/trigger_consumer.h> #include "ad799x.h" @@ -32,9 +32,7 @@ **/ static int ad799x_ring_preenable(struct iio_dev *indio_dev) { - struct iio_buffer *ring = indio_dev->buffer; struct ad799x_state *st = iio_priv(indio_dev); - /* * Need to figure out the current mode based upon the requested * scan mask in iio_dev @@ -43,21 +41,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) if (st->id == ad7997 || st->id == ad7998) ad7997_8_set_scan_mode(st, *indio_dev->active_scan_mask); - st->d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * 2; - - if (ring->scan_timestamp) { - st->d_size += sizeof(s64); - - if (st->d_size % sizeof(s64)) - st->d_size += sizeof(s64) - (st->d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, st->d_size); - - return 0; + return iio_sw_buffer_preenable(indio_dev); } /** @@ -78,7 +62,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) int b_sent; u8 cmd; - rxbuf = kmalloc(st->d_size, GFP_KERNEL); + rxbuf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (rxbuf == NULL) goto out; @@ -111,8 +95,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (ring->scan_timestamp) - memcpy(rxbuf + st->d_size - sizeof(s64), + if (indio_dev->scan_timestamp) + memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); ring->access->store_to(indio_dev->buffer, rxbuf, time_ns); @@ -136,7 +120,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) { int ret = 0; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -150,7 +134,7 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->id); if (indio_dev->pollfunc == NULL) { ret = -ENOMEM; - goto error_deallocate_sw_rb; + goto error_deallocate_kfifo; } /* Ring buffer functions - here trigger setup related */ @@ -161,8 +145,8 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev) indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; -error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); +error_deallocate_kfifo: + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -170,5 +154,5 @@ error_ret: void ad799x_ring_cleanup(struct iio_dev *indio_dev) { iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index caf57c1..e5f1ed7 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -15,9 +15,9 @@ #include <linux/spi/spi.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> /* * ADT7310 registers definition */ @@ -175,7 +175,7 @@ static ssize_t adt7310_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u8 config; @@ -198,7 +198,7 @@ static ssize_t adt7310_store_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -242,7 +242,7 @@ static ssize_t adt7310_show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; int bits; @@ -264,7 +264,7 @@ static ssize_t adt7310_store_resolution(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); unsigned long data; u16 config; @@ -300,7 +300,7 @@ static ssize_t adt7310_show_id(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -350,7 +350,7 @@ static ssize_t adt7310_show_value(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u8 status; u16 data; @@ -424,7 +424,7 @@ static ssize_t adt7310_show_event_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; @@ -443,7 +443,7 @@ static ssize_t adt7310_set_event_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -476,7 +476,7 @@ static ssize_t adt7310_show_fault_queue(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; @@ -492,7 +492,7 @@ static ssize_t adt7310_set_fault_queue(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -522,7 +522,7 @@ static inline ssize_t adt7310_show_t_bound(struct device *dev, u8 bound_reg, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); u16 data; int ret; @@ -540,7 +540,7 @@ static inline ssize_t adt7310_set_t_bound(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); long tmp1, tmp2; u16 data; @@ -660,7 +660,7 @@ static ssize_t adt7310_show_t_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; u8 t_hyst; @@ -677,7 +677,7 @@ static inline ssize_t adt7310_set_t_hyst(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; unsigned long data; @@ -753,7 +753,7 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev) unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; unsigned long irq_flags; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -833,7 +833,7 @@ error_unreg_int_irq: error_unreg_ct_irq: free_irq(spi_dev->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -849,7 +849,7 @@ static int __devexit adt7310_remove(struct spi_device *spi_dev) free_irq(adt7310_platform_data[0], indio_dev); if (spi_dev->irq) free_irq(spi_dev->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index dff3e8c..917b692 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -15,9 +15,9 @@ #include <linux/i2c.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> /* * ADT7410 registers definition @@ -144,7 +144,7 @@ static ssize_t adt7410_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u8 config; @@ -167,7 +167,7 @@ static ssize_t adt7410_store_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -211,7 +211,7 @@ static ssize_t adt7410_show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; int bits; @@ -233,7 +233,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); unsigned long data; u16 config; @@ -269,7 +269,7 @@ static ssize_t adt7410_show_id(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -319,7 +319,7 @@ static ssize_t adt7410_show_value(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u8 status; u16 data; @@ -392,7 +392,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; @@ -411,7 +411,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -444,7 +444,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; @@ -460,7 +460,7 @@ static ssize_t adt7410_set_fault_queue(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -490,7 +490,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev, u8 bound_reg, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); u16 data; int ret; @@ -508,7 +508,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); long tmp1, tmp2; u16 data; @@ -628,7 +628,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; u8 t_hyst; @@ -645,7 +645,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; unsigned long data; @@ -721,7 +721,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, int ret = 0; unsigned long *adt7410_platform_data = client->dev.platform_data; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -797,7 +797,7 @@ error_unreg_int_irq: error_unreg_ct_irq: free_irq(client->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -812,7 +812,7 @@ static int __devexit adt7410_remove(struct i2c_client *client) free_irq(adt7410_platform_data[0], indio_dev); if (client->irq) free_irq(client->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index dfc9033..9690306 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -30,9 +30,10 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/completion.h> +#include <linux/of.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> /* * LPC32XX registers definitions @@ -73,7 +74,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev, { struct lpc32xx_adc_info *info = iio_priv(indio_dev); - if (mask == 0) { + if (mask == IIO_CHAN_INFO_RAW) { mutex_lock(&indio_dev->mlock); clk_enable(info->clk); /* Measurement setup */ @@ -98,12 +99,13 @@ static const struct iio_info lpc32xx_adc_iio_info = { .driver_module = THIS_MODULE, }; -#define LPC32XX_ADC_CHANNEL(_index) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = _index, \ - .address = AD_IN * _index, \ - .scan_index = _index, \ +#define LPC32XX_ADC_CHANNEL(_index) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .address = AD_IN * _index, \ + .scan_index = _index, \ } static struct iio_chan_spec lpc32xx_adc_iio_channels[] = { @@ -139,7 +141,7 @@ static int __devinit lpc32xx_adc_probe(struct platform_device *pdev) goto errout1; } - iodev = iio_allocate_device(sizeof(struct lpc32xx_adc_info)); + iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info)); if (!iodev) { dev_err(&pdev->dev, "failed allocating iio device\n"); retval = -ENOMEM; @@ -200,7 +202,7 @@ errout4: errout3: iounmap(info->adc_base); errout2: - iio_free_device(iodev); + iio_device_free(iodev); errout1: return retval; } @@ -216,17 +218,26 @@ static int __devexit lpc32xx_adc_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); clk_put(info->clk); iounmap(info->adc_base); - iio_free_device(iodev); + iio_device_free(iodev); return 0; } +#ifdef CONFIG_OF +static const struct of_device_id lpc32xx_adc_match[] = { + { .compatible = "nxp,lpc3220-adc" }, + {}, +}; +MODULE_DEVICE_TABLE(of, lpc32xx_adc_match); +#endif + static struct platform_driver lpc32xx_adc_driver = { .probe = lpc32xx_adc_probe, .remove = __devexit_p(lpc32xx_adc_remove), .driver = { .name = MOD_NAME, .owner = THIS_MODULE, + .of_match_table = of_match_ptr(lpc32xx_adc_match), }, }; diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index cf3e2ca..6799ce2 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -32,10 +32,11 @@ #include <linux/err.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/buffer.h> +#include <linux/iio/driver.h> #include "max1363.h" @@ -248,7 +249,7 @@ static int max1363_read_raw(struct iio_dev *indio_dev, struct max1363_state *st = iio_priv(indio_dev); int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = max1363_read_single_chan(indio_dev, chan, val, m); if (ret < 0) return ret; @@ -281,7 +282,8 @@ static const enum max1363_modes max1363_mode_list[] = { #define MAX1363_EV_M \ (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) -#define MAX1363_INFO_MASK IIO_CHAN_INFO_SCALE_SHARED_BIT +#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT) #define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ { \ .type = IIO_VOLTAGE, \ @@ -497,7 +499,7 @@ static ssize_t max1363_monitor_show_freq(struct device *dev, struct device_attribute *attr, char *buf) { - struct max1363_state *st = iio_priv(dev_get_drvdata(dev)); + struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); } @@ -506,7 +508,7 @@ static ssize_t max1363_monitor_store_freq(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct max1363_state *st = iio_priv(indio_dev); int i, ret; unsigned long val; @@ -830,6 +832,7 @@ static struct attribute_group max1363_event_attribute_group = { static const struct iio_info max1238_info = { .read_raw = &max1363_read_raw, .driver_module = THIS_MODULE, + .update_scan_mode = &max1363_update_scan_mode, }; static const struct iio_info max1363_info = { @@ -1284,11 +1287,14 @@ static int __devinit max1363_probe(struct i2c_client *client, if (ret) goto error_put_reg; - indio_dev = iio_allocate_device(sizeof(struct max1363_state)); + indio_dev = iio_device_alloc(sizeof(struct max1363_state)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; } + ret = iio_map_array_register(indio_dev, client->dev.platform_data); + if (ret < 0) + goto error_free_device; st = iio_priv(indio_dev); st->reg = reg; /* this is only used for device removal purposes */ @@ -1299,7 +1305,7 @@ static int __devinit max1363_probe(struct i2c_client *client, ret = max1363_alloc_scan_masks(indio_dev); if (ret) - goto error_free_device; + goto error_unregister_map; /* Estabilish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; @@ -1349,8 +1355,10 @@ error_cleanup_ring: max1363_ring_cleanup(indio_dev); error_free_available_scan_masks: kfree(indio_dev->available_scan_masks); +error_unregister_map: + iio_map_array_unregister(indio_dev, client->dev.platform_data); error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: regulator_disable(reg); error_put_reg: @@ -1375,7 +1383,8 @@ static int max1363_remove(struct i2c_client *client) regulator_disable(reg); regulator_put(reg); } - iio_free_device(indio_dev); + iio_map_array_unregister(indio_dev, client->dev.platform_data); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index d0a60a3..b302013 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -14,10 +14,10 @@ #include <linux/i2c.h> #include <linux/bitops.h> -#include "../iio.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/buffer.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "max1363.h" @@ -54,7 +54,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) d_size = numvals*2; else d_size = numvals; - if (indio_dev->buffer->scan_timestamp) { + if (indio_dev->scan_timestamp) { d_size += sizeof(s64); if (d_size % sizeof(s64)) d_size += sizeof(s64) - (d_size % sizeof(s64)); @@ -78,7 +78,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) time_ns = iio_get_time_ns(); - if (indio_dev->buffer->scan_timestamp) + if (indio_dev->scan_timestamp) memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); iio_push_to_buffer(indio_dev->buffer, rxbuf, time_ns); diff --git a/drivers/staging/iio/adc/spear_adc.c b/drivers/staging/iio/adc/spear_adc.c new file mode 100644 index 0000000..64d630e --- /dev/null +++ b/drivers/staging/iio/adc/spear_adc.c @@ -0,0 +1,448 @@ +/* + * ST SPEAr ADC driver + * + * Copyright 2012 Stefan Roese <sr@denx.de> + * + * Licensed under the GPL-2. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/completion.h> +#include <linux/of.h> +#include <linux/of_address.h> + +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +/* + * SPEAR registers definitions + */ + +#define SCAN_RATE_LO(x) ((x) & 0xFFFF) +#define SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF) +#define CLK_LOW(x) (((x) & 0xf) << 0) +#define CLK_HIGH(x) (((x) & 0xf) << 4) + +/* Bit definitions for SPEAR_ADC_STATUS */ +#define START_CONVERSION (1 << 0) +#define CHANNEL_NUM(x) ((x) << 1) +#define ADC_ENABLE (1 << 4) +#define AVG_SAMPLE(x) ((x) << 5) +#define VREF_INTERNAL (1 << 9) + +#define DATA_MASK 0x03ff +#define DATA_BITS 10 + +#define MOD_NAME "spear-adc" + +#define ADC_CHANNEL_NUM 8 + +#define CLK_MIN 2500000 +#define CLK_MAX 20000000 + +struct adc_regs_spear3xx { + u32 status; + u32 average; + u32 scan_rate; + u32 clk; /* Not avail for 1340 & 1310 */ + u32 ch_ctrl[ADC_CHANNEL_NUM]; + u32 ch_data[ADC_CHANNEL_NUM]; +}; + +struct chan_data { + u32 lsb; + u32 msb; +}; + +struct adc_regs_spear6xx { + u32 status; + u32 pad[2]; + u32 clk; + u32 ch_ctrl[ADC_CHANNEL_NUM]; + struct chan_data ch_data[ADC_CHANNEL_NUM]; + u32 scan_rate_lo; + u32 scan_rate_hi; + struct chan_data average; +}; + +struct spear_adc_info { + struct device_node *np; + struct adc_regs_spear3xx __iomem *adc_base_spear3xx; + struct adc_regs_spear6xx __iomem *adc_base_spear6xx; + struct clk *clk; + struct completion completion; + u32 current_clk; + u32 sampling_freq; + u32 avg_samples; + u32 vref_external; + u32 value; +}; + +/* + * Functions to access some SPEAr ADC register. Abstracted into + * static inline functions, because of different register offsets + * on different SoC variants (SPEAr300 vs SPEAr600 etc). + */ +static void spear_adc_set_status(struct spear_adc_info *info, u32 val) +{ + __raw_writel(val, &info->adc_base_spear6xx->status); +} + +static void spear_adc_set_clk(struct spear_adc_info *info, u32 val) +{ + u32 clk_high, clk_low, count; + u32 apb_clk = clk_get_rate(info->clk); + + count = (apb_clk + val - 1) / val; + clk_low = count / 2; + clk_high = count - clk_low; + info->current_clk = apb_clk / count; + + __raw_writel(CLK_LOW(clk_low) | CLK_HIGH(clk_high), + &info->adc_base_spear6xx->clk); +} + +static void spear_adc_set_ctrl(struct spear_adc_info *info, int n, + u32 val) +{ + __raw_writel(val, &info->adc_base_spear6xx->ch_ctrl[n]); +} + +static u32 spear_adc_get_average(struct spear_adc_info *info) +{ + if (of_device_is_compatible(info->np, "st,spear600-adc")) { + return __raw_readl(&info->adc_base_spear6xx->average.msb) & + DATA_MASK; + } else { + return __raw_readl(&info->adc_base_spear3xx->average) & + DATA_MASK; + } +} + +static void spear_adc_set_scanrate(struct spear_adc_info *info, u32 rate) +{ + if (of_device_is_compatible(info->np, "st,spear600-adc")) { + __raw_writel(SCAN_RATE_LO(rate), + &info->adc_base_spear6xx->scan_rate_lo); + __raw_writel(SCAN_RATE_HI(rate), + &info->adc_base_spear6xx->scan_rate_hi); + } else { + __raw_writel(rate, &info->adc_base_spear3xx->scan_rate); + } +} + +static int spear_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct spear_adc_info *info = iio_priv(indio_dev); + u32 scale_mv; + u32 status; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + + status = CHANNEL_NUM(chan->channel) | + AVG_SAMPLE(info->avg_samples) | + START_CONVERSION | ADC_ENABLE; + if (info->vref_external == 0) + status |= VREF_INTERNAL; + + spear_adc_set_status(info, status); + wait_for_completion(&info->completion); /* set by ISR */ + *val = info->value; + + mutex_unlock(&indio_dev->mlock); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + scale_mv = (info->vref_external * 1000) >> DATA_BITS; + *val = scale_mv / 1000; + *val2 = (scale_mv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; +} + +#define SPEAR_ADC_CHAN(idx) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .channel = idx, \ + .scan_type = { \ + .sign = 'u', \ + .storagebits = 16, \ + }, \ +} + +static struct iio_chan_spec spear_adc_iio_channels[] = { + SPEAR_ADC_CHAN(0), + SPEAR_ADC_CHAN(1), + SPEAR_ADC_CHAN(2), + SPEAR_ADC_CHAN(3), + SPEAR_ADC_CHAN(4), + SPEAR_ADC_CHAN(5), + SPEAR_ADC_CHAN(6), + SPEAR_ADC_CHAN(7), +}; + +static irqreturn_t spear_adc_isr(int irq, void *dev_id) +{ + struct spear_adc_info *info = (struct spear_adc_info *)dev_id; + + /* Read value to clear IRQ */ + info->value = spear_adc_get_average(info); + complete(&info->completion); + + return IRQ_HANDLED; +} + +static int spear_adc_configure(struct spear_adc_info *info) +{ + int i; + + /* Reset ADC core */ + spear_adc_set_status(info, 0); + __raw_writel(0, &info->adc_base_spear6xx->clk); + for (i = 0; i < 8; i++) + spear_adc_set_ctrl(info, i, 0); + spear_adc_set_scanrate(info, 0); + + spear_adc_set_clk(info, info->sampling_freq); + + return 0; +} + +static ssize_t spear_adc_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct spear_adc_info *info = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", info->current_clk); +} + +static ssize_t spear_adc_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct spear_adc_info *info = iio_priv(indio_dev); + u32 clk_high, clk_low, count; + u32 apb_clk = clk_get_rate(info->clk); + unsigned long lval; + int ret; + + ret = kstrtoul(buf, 10, &lval); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + if ((lval < CLK_MIN) || (lval > CLK_MAX)) { + ret = -EINVAL; + goto out; + } + + count = (apb_clk + lval - 1) / lval; + clk_low = count / 2; + clk_high = count - clk_low; + info->current_clk = apb_clk / count; + spear_adc_set_clk(info, lval); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + spear_adc_read_frequency, + spear_adc_write_frequency); + +static struct attribute *spear_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL +}; + +static const struct attribute_group spear_attribute_group = { + .attrs = spear_attributes, +}; + +static const struct iio_info spear_adc_iio_info = { + .read_raw = &spear_read_raw, + .attrs = &spear_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit spear_adc_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct spear_adc_info *info; + struct iio_dev *iodev = NULL; + int ret = -ENODEV; + int irq; + + iodev = iio_device_alloc(sizeof(struct spear_adc_info)); + if (!iodev) { + dev_err(dev, "failed allocating iio device\n"); + ret = -ENOMEM; + goto errout1; + } + + info = iio_priv(iodev); + info->np = np; + + /* + * SPEAr600 has a different register layout than other SPEAr SoC's + * (e.g. SPEAr3xx). Let's provide two register base addresses + * to support multi-arch kernels. + */ + info->adc_base_spear6xx = of_iomap(np, 0); + if (!info->adc_base_spear6xx) { + dev_err(dev, "failed mapping memory\n"); + ret = -ENOMEM; + goto errout2; + } + info->adc_base_spear3xx = + (struct adc_regs_spear3xx *)info->adc_base_spear6xx; + + info->clk = clk_get(dev, NULL); + if (IS_ERR(info->clk)) { + dev_err(dev, "failed getting clock\n"); + goto errout3; + } + + ret = clk_prepare(info->clk); + if (ret) { + dev_err(dev, "failed preparing clock\n"); + goto errout4; + } + + ret = clk_enable(info->clk); + if (ret) { + dev_err(dev, "failed enabling clock\n"); + goto errout5; + } + + irq = platform_get_irq(pdev, 0); + if ((irq < 0) || (irq >= NR_IRQS)) { + dev_err(dev, "failed getting interrupt resource\n"); + ret = -EINVAL; + goto errout6; + } + + ret = devm_request_irq(dev, irq, spear_adc_isr, 0, MOD_NAME, info); + if (ret < 0) { + dev_err(dev, "failed requesting interrupt\n"); + goto errout6; + } + + if (of_property_read_u32(np, "sampling-frequency", + &info->sampling_freq)) { + dev_err(dev, "sampling-frequency missing in DT\n"); + ret = -EINVAL; + goto errout6; + } + + /* + * Optional avg_samples defaults to 0, resulting in single data + * conversion + */ + of_property_read_u32(np, "average-samples", &info->avg_samples); + + /* + * Optional vref_external defaults to 0, resulting in internal vref + * selection + */ + of_property_read_u32(np, "vref-external", &info->vref_external); + + spear_adc_configure(info); + + platform_set_drvdata(pdev, iodev); + + init_completion(&info->completion); + + iodev->name = MOD_NAME; + iodev->dev.parent = dev; + iodev->info = &spear_adc_iio_info; + iodev->modes = INDIO_DIRECT_MODE; + iodev->channels = spear_adc_iio_channels; + iodev->num_channels = ARRAY_SIZE(spear_adc_iio_channels); + + ret = iio_device_register(iodev); + if (ret) + goto errout6; + + dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq); + + return 0; + +errout6: + clk_disable(info->clk); +errout5: + clk_unprepare(info->clk); +errout4: + clk_put(info->clk); +errout3: + iounmap(info->adc_base_spear6xx); +errout2: + iio_device_free(iodev); +errout1: + return ret; +} + +static int __devexit spear_adc_remove(struct platform_device *pdev) +{ + struct iio_dev *iodev = platform_get_drvdata(pdev); + struct spear_adc_info *info = iio_priv(iodev); + + iio_device_unregister(iodev); + platform_set_drvdata(pdev, NULL); + clk_disable(info->clk); + clk_unprepare(info->clk); + clk_put(info->clk); + iounmap(info->adc_base_spear6xx); + iio_device_free(iodev); + + return 0; +} + +static const struct of_device_id spear_adc_dt_ids[] = { + { .compatible = "st,spear600-adc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spear_adc_dt_ids); + +static struct platform_driver spear_adc_driver = { + .probe = spear_adc_probe, + .remove = __devexit_p(spear_adc_remove), + .driver = { + .name = MOD_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(spear_adc_dt_ids), + }, +}; + +module_platform_driver(spear_adc_driver); + +MODULE_AUTHOR("Stefan Roese <sr@denx.de>"); +MODULE_DESCRIPTION("SPEAr ADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index fd6a454..8fb014a 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -19,9 +19,9 @@ #include <linux/rtc.h> #include <linux/module.h> -#include "../iio.h" -#include "../events.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/events.h> +#include <linux/iio/sysfs.h> #include "adt7316.h" /* @@ -220,7 +220,7 @@ static ssize_t adt7316_show_enabled(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN)); @@ -252,7 +252,7 @@ static ssize_t adt7316_store_enabled(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); int enable; @@ -276,7 +276,7 @@ static ssize_t adt7316_show_select_ex_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) @@ -290,7 +290,7 @@ static ssize_t adt7316_store_select_ex_temp(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -320,7 +320,7 @@ static ssize_t adt7316_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE) @@ -334,7 +334,7 @@ static ssize_t adt7316_store_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -370,7 +370,7 @@ static ssize_t adt7316_show_ad_channel(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) @@ -409,7 +409,7 @@ static ssize_t adt7316_store_ad_channel(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; unsigned long data = 0; @@ -455,7 +455,7 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) @@ -477,7 +477,7 @@ static ssize_t adt7316_show_disable_averaging(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", @@ -489,7 +489,7 @@ static ssize_t adt7316_store_disable_averaging(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -516,7 +516,7 @@ static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", @@ -528,7 +528,7 @@ static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -557,7 +557,7 @@ static ssize_t adt7316_store_reset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -580,7 +580,7 @@ static ssize_t adt7316_show_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD)); @@ -591,7 +591,7 @@ static ssize_t adt7316_store_powerdown(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -618,7 +618,7 @@ static ssize_t adt7316_show_fast_ad_clock(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5)); @@ -629,7 +629,7 @@ static ssize_t adt7316_store_fast_ad_clock(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -656,7 +656,7 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { @@ -674,7 +674,7 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -708,7 +708,7 @@ static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) @@ -723,7 +723,7 @@ static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -755,7 +755,7 @@ static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", @@ -767,7 +767,7 @@ static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -794,7 +794,7 @@ static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", @@ -806,7 +806,7 @@ static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -833,7 +833,7 @@ static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%x\n", @@ -845,7 +845,7 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; unsigned long data = 0; @@ -876,7 +876,7 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) @@ -900,7 +900,7 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; unsigned long data; @@ -934,7 +934,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) @@ -955,7 +955,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 ldac_config; unsigned long data; @@ -994,7 +994,7 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) @@ -1009,7 +1009,7 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; int ret; @@ -1039,7 +1039,7 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) @@ -1054,7 +1054,7 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; int ret; @@ -1084,7 +1084,7 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) @@ -1101,7 +1101,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 ldac_config; unsigned long data; @@ -1220,7 +1220,7 @@ static ssize_t adt7316_show_VDD(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf); @@ -1231,7 +1231,7 @@ static ssize_t adt7316_show_in_temp(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf); @@ -1243,7 +1243,7 @@ static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf); @@ -1256,7 +1256,7 @@ static ssize_t adt7316_show_AIN2(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf); @@ -1267,7 +1267,7 @@ static ssize_t adt7316_show_AIN3(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf); @@ -1278,7 +1278,7 @@ static ssize_t adt7316_show_AIN4(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf); @@ -1330,7 +1330,7 @@ static ssize_t adt7316_show_in_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf); @@ -1341,7 +1341,7 @@ static ssize_t adt7316_store_in_temp_offset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len); @@ -1355,7 +1355,7 @@ static ssize_t adt7316_show_ex_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf); @@ -1366,7 +1366,7 @@ static ssize_t adt7316_store_ex_temp_offset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len); @@ -1380,7 +1380,7 @@ static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, @@ -1392,7 +1392,7 @@ static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, @@ -1407,7 +1407,7 @@ static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, @@ -1419,7 +1419,7 @@ static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, @@ -1504,7 +1504,7 @@ static ssize_t adt7316_show_DAC_A(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 0, buf); @@ -1515,7 +1515,7 @@ static ssize_t adt7316_store_DAC_A(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 0, buf, len); @@ -1528,7 +1528,7 @@ static ssize_t adt7316_show_DAC_B(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 1, buf); @@ -1539,7 +1539,7 @@ static ssize_t adt7316_store_DAC_B(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 1, buf, len); @@ -1552,7 +1552,7 @@ static ssize_t adt7316_show_DAC_C(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 2, buf); @@ -1563,7 +1563,7 @@ static ssize_t adt7316_store_DAC_C(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 2, buf, len); @@ -1576,7 +1576,7 @@ static ssize_t adt7316_show_DAC_D(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 3, buf); @@ -1587,7 +1587,7 @@ static ssize_t adt7316_store_DAC_D(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 3, buf, len); @@ -1600,7 +1600,7 @@ static ssize_t adt7316_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -1618,7 +1618,7 @@ static ssize_t adt7316_show_manufactorer_id(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -1637,7 +1637,7 @@ static ssize_t adt7316_show_device_rev(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 rev; int ret; @@ -1655,7 +1655,7 @@ static ssize_t adt7316_show_bus_type(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 stat; int ret; @@ -1841,7 +1841,7 @@ static ssize_t adt7316_show_int_mask(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%x\n", chip->int_mask); @@ -1855,7 +1855,7 @@ static ssize_t adt7316_set_int_mask(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -1895,7 +1895,7 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev, char *buf) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 val; int data; @@ -1926,7 +1926,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); long data; u8 val; @@ -1965,7 +1965,7 @@ static ssize_t adt7316_show_int_enabled(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN)); @@ -1976,7 +1976,7 @@ static ssize_t adt7316_set_int_enabled(struct device *dev, const char *buf, size_t len) { - struct iio_dev *dev_info = dev_get_drvdata(dev); + struct iio_dev *dev_info = dev_to_iio_dev(dev); struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -2133,7 +2133,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, unsigned short *adt7316_platform_data = dev->platform_data; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -2210,7 +2210,7 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, error_unreg_irq: free_irq(chip->bus.irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -2224,7 +2224,7 @@ int __devexit adt7316_remove(struct device *dev) iio_device_unregister(indio_dev); if (chip->bus.irq) free_irq(chip->bus.irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/buffer.h b/drivers/staging/iio/buffer.h deleted file mode 100644 index df2046d..0000000 --- a/drivers/staging/iio/buffer.h +++ /dev/null @@ -1,193 +0,0 @@ -/* The industrial I/O core - generic buffer interfaces. - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_BUFFER_GENERIC_H_ -#define _IIO_BUFFER_GENERIC_H_ -#include <linux/sysfs.h> -#include "iio.h" - -#ifdef CONFIG_IIO_BUFFER - -struct iio_buffer; - -/** - * struct iio_buffer_access_funcs - access functions for buffers. - * @store_to: actually store stuff to the buffer - * @read_first_n: try to get a specified number of bytes (must exist) - * @request_update: if a parameter change has been marked, update underlying - * storage. - * @get_bytes_per_datum:get current bytes per datum - * @set_bytes_per_datum:set number of bytes per datum - * @get_length: get number of datums in buffer - * @set_length: set number of datums in buffer - * - * The purpose of this structure is to make the buffer element - * modular as event for a given driver, different usecases may require - * different buffer designs (space efficiency vs speed for example). - * - * It is worth noting that a given buffer implementation may only support a - * small proportion of these functions. The core code 'should' cope fine with - * any of them not existing. - **/ -struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); - int (*read_first_n)(struct iio_buffer *buffer, - size_t n, - char __user *buf); - - int (*request_update)(struct iio_buffer *buffer); - - int (*get_bytes_per_datum)(struct iio_buffer *buffer); - int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); - int (*get_length)(struct iio_buffer *buffer); - int (*set_length)(struct iio_buffer *buffer, int length); -}; - -/** - * struct iio_buffer - general buffer structure - * @length: [DEVICE] number of datums in buffer - * @bytes_per_datum: [DEVICE] size of individual datum including timestamp - * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode - * control method is used - * @scan_mask: [INTERN] bitmask used in masking scan mode elements - * @scan_index_timestamp:[INTERN] cache of the index to the timestamp - * @scan_timestamp: [INTERN] does the scan mode include a timestamp - * @access: [DRIVER] buffer access functions associated with the - * implementation. - * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes. - * @scan_el_group: [DRIVER] attribute group for those attributes not - * created from the iio_chan_info array. - * @pollq: [INTERN] wait queue to allow for polling on the buffer. - * @stufftoread: [INTERN] flag to indicate new data. - * @demux_list: [INTERN] list of operations required to demux the scan. - * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. - **/ -struct iio_buffer { - int length; - int bytes_per_datum; - struct attribute_group *scan_el_attrs; - long *scan_mask; - bool scan_timestamp; - unsigned scan_index_timestamp; - const struct iio_buffer_access_funcs *access; - struct list_head scan_el_dev_attr_list; - struct attribute_group scan_el_group; - wait_queue_head_t pollq; - bool stufftoread; - const struct attribute_group *attrs; - struct list_head demux_list; - unsigned char *demux_bounce; -}; - -/** - * iio_buffer_init() - Initialize the buffer structure - * @buffer: buffer to be initialized - **/ -void iio_buffer_init(struct iio_buffer *buffer); - -/** - * __iio_update_buffer() - update common elements of buffers - * @buffer: buffer that is the event source - * @bytes_per_datum: size of individual datum including timestamp - * @length: number of datums in buffer - **/ -static inline void __iio_update_buffer(struct iio_buffer *buffer, - int bytes_per_datum, int length) -{ - buffer->bytes_per_datum = bytes_per_datum; - buffer->length = length; -} - -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); - -/** - * iio_scan_mask_set() - set particular bit in the scan mask - * @buffer: the buffer whose scan mask we are interested in - * @bit: the bit to be set. - **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit); - -/** - * iio_push_to_buffer() - push to a registered buffer. - * @buffer: IIO buffer structure for device - * @scan: Full scan. - * @timestamp: - */ -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp); - -int iio_update_demux(struct iio_dev *indio_dev); - -/** - * iio_buffer_register() - register the buffer with IIO core - * @indio_dev: device with the buffer to be registered - **/ -int iio_buffer_register(struct iio_dev *indio_dev, - const struct iio_chan_spec *channels, - int num_channels); - -/** - * iio_buffer_unregister() - unregister the buffer from IIO core - * @indio_dev: the device with the buffer to be unregistered - **/ -void iio_buffer_unregister(struct iio_dev *indio_dev); - -/** - * iio_buffer_read_length() - attr func to get number of datums in the buffer - **/ -ssize_t iio_buffer_read_length(struct device *dev, - struct device_attribute *attr, - char *buf); -/** - * iio_buffer_write_length() - attr func to set number of datums in the buffer - **/ -ssize_t iio_buffer_write_length(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len); -/** - * iio_buffer_store_enable() - attr to turn the buffer on - **/ -ssize_t iio_buffer_store_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len); -/** - * iio_buffer_show_enable() - attr to see if the buffer is on - **/ -ssize_t iio_buffer_show_enable(struct device *dev, - struct device_attribute *attr, - char *buf); -#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR, \ - iio_buffer_read_length, \ - iio_buffer_write_length) - -#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \ - iio_buffer_show_enable, \ - iio_buffer_store_enable) - -int iio_sw_buffer_preenable(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline int iio_buffer_register(struct iio_dev *indio_dev, - struct iio_chan_spec *channels, - int num_channels) -{ - return 0; -} - -static inline void iio_buffer_unregister(struct iio_dev *indio_dev) -{}; - -#endif /* CONFIG_IIO_BUFFER */ - -#endif /* _IIO_BUFFER_GENERIC_H_ */ diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index e4a08dc..a16d1a2 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -13,9 +13,9 @@ #include <linux/i2c.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> /* * AD7150 registers definition */ @@ -104,7 +104,7 @@ static int ad7150_read_raw(struct iio_dev *indio_dev, struct ad7150_chip_info *chip = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = i2c_smbus_read_word_data(chip->client, ad7150_addresses[chan->channel][0]); if (ret < 0) @@ -341,7 +341,7 @@ static ssize_t ad7150_show_timeout(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7150_chip_info *chip = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u8 value; @@ -370,7 +370,7 @@ static ssize_t ad7150_store_timeout(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7150_chip_info *chip = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address); @@ -429,7 +429,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | @@ -441,7 +442,8 @@ static const struct iio_chan_spec ad7150_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT, .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) | @@ -556,7 +558,7 @@ static int __devinit ad7150_probe(struct i2c_client *client, struct ad7150_chip_info *chip; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -619,7 +621,7 @@ error_free_irq: if (client->irq) free_irq(client->irq, indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -635,7 +637,7 @@ static int __devexit ad7150_remove(struct i2c_client *client) if (client->dev.platform_data) free_irq(*(unsigned int *)client->dev.platform_data, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index fdb83c3..98c3015 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -15,8 +15,8 @@ #include <linux/module.h> #include <linux/delay.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> /* * TODO: Check compliance of calibbias with abi (units) @@ -97,7 +97,7 @@ static inline ssize_t ad7152_start_calib(struct device *dev, size_t len, u8 regval) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7152_chip_info *chip = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); bool doit; @@ -169,7 +169,7 @@ static ssize_t ad7152_show_filter_rate_setup(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7152_chip_info *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", @@ -181,7 +181,7 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7152_chip_info *chip = iio_priv(indio_dev); u8 data; int ret, i; @@ -329,7 +329,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* First set whether in differential mode */ regval = chip->setup[chan->channel]; @@ -436,7 +436,8 @@ static const struct iio_chan_spec ad7152_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { @@ -445,14 +446,16 @@ static const struct iio_chan_spec ad7152_channels[] = { .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { @@ -461,7 +464,8 @@ static const struct iio_chan_spec ad7152_channels[] = { .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } @@ -477,7 +481,7 @@ static int __devinit ad7152_probe(struct i2c_client *client, struct ad7152_chip_info *chip; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -509,7 +513,7 @@ static int __devinit ad7152_probe(struct i2c_client *client, return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -519,7 +523,7 @@ static int __devexit ad7152_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 40b8512..754e11e 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -16,8 +16,8 @@ #include <linux/module.h> #include <linux/stat.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "ad7746.h" @@ -123,7 +123,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_VIN, }, @@ -132,7 +133,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_VDD_MON, }, @@ -140,7 +142,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .processed_val = IIO_PROCESSED, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_INT_TEMP, }, @@ -148,7 +150,7 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 1, - .processed_val = IIO_PROCESSED, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .address = AD7746_REG_VT_DATA_HIGH << 8 | AD7746_VTSETUP_VTMD_EXT_TEMP, }, @@ -156,7 +158,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -168,7 +171,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 0, .channel2 = 2, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -179,7 +183,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .type = IIO_CAPACITANCE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -192,7 +197,8 @@ static const struct iio_chan_spec ad7746_channels[] = { .indexed = 1, .channel = 1, .channel2 = 3, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, @@ -280,7 +286,7 @@ static inline ssize_t ad7746_start_calib(struct device *dev, size_t len, u8 regval) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7746_chip_info *chip = iio_priv(indio_dev); bool doit; int ret, timeout = 10; @@ -319,7 +325,7 @@ static ssize_t ad7746_start_offset_calib(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret = ad7746_select_channel(indio_dev, &ad7746_channels[to_iio_dev_attr(attr)->address]); if (ret < 0) @@ -334,7 +340,7 @@ static ssize_t ad7746_start_gain_calib(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret = ad7746_select_channel(indio_dev, &ad7746_channels[to_iio_dev_attr(attr)->address]); if (ret < 0) @@ -359,7 +365,7 @@ static ssize_t ad7746_show_cap_filter_rate_setup(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7746_chip_info *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", ad7746_cap_filter_rate_table[ @@ -371,7 +377,7 @@ static ssize_t ad7746_store_cap_filter_rate_setup(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7746_chip_info *chip = iio_priv(indio_dev); u8 data; int ret, i; @@ -399,7 +405,7 @@ static ssize_t ad7746_show_vt_filter_rate_setup(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7746_chip_info *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", ad7746_vt_filter_rate_table[ @@ -411,7 +417,7 @@ static ssize_t ad7746_store_vt_filter_rate_setup(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7746_chip_info *chip = iio_priv(indio_dev); u8 data; int ret, i; @@ -572,7 +578,8 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: ret = ad7746_select_channel(indio_dev, chan); if (ret < 0) goto out; @@ -696,7 +703,7 @@ static int __devinit ad7746_probe(struct i2c_client *client, int ret = 0; unsigned char regval = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -756,7 +763,7 @@ static int __devinit ad7746_probe(struct i2c_client *client, return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -766,7 +773,7 @@ static int __devexit ad7746_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/consumer.h b/drivers/staging/iio/consumer.h deleted file mode 100644 index 36a060c..0000000 --- a/drivers/staging/iio/consumer.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Industrial I/O in kernel consumer interface - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _IIO_INKERN_CONSUMER_H_ -#define _IIO_INKERN_CONSUMER_H -#include "types.h" - -struct iio_dev; -struct iio_chan_spec; - -/** - * struct iio_channel - everything needed for a consumer to use a channel - * @indio_dev: Device on which the channel exists. - * @channel: Full description of the channel. - */ -struct iio_channel { - struct iio_dev *indio_dev; - const struct iio_chan_spec *channel; -}; - -/** - * iio_channel_get() - get description of all that is needed to access channel. - * @name: Unique name of the device as provided in the iio_map - * with which the desired provider to consumer mapping - * was registered. - * @consumer_channel: Unique name to identify the channel on the consumer - * side. This typically describes the channels use within - * the consumer. E.g. 'battery_voltage' - */ -struct iio_channel *iio_st_channel_get(const char *name, - const char *consumer_channel); - -/** - * iio_st_channel_release() - release channels obtained via iio_st_channel_get - * @chan: The channel to be released. - */ -void iio_st_channel_release(struct iio_channel *chan); - -/** - * iio_st_channel_get_all() - get all channels associated with a client - * @name: name of consumer device. - * - * Returns an array of iio_channel structures terminated with one with - * null iio_dev pointer. - * This function is used by fairly generic consumers to get all the - * channels registered as having this consumer. - */ -struct iio_channel *iio_st_channel_get_all(const char *name); - -/** - * iio_st_channel_release_all() - reverse iio_st_get_all - * @chan: Array of channels to be released. - */ -void iio_st_channel_release_all(struct iio_channel *chan); - -/** - * iio_st_read_channel_raw() - read from a given channel - * @channel: The channel being queried. - * @val: Value read back. - * - * Note raw reads from iio channels are in adc counts and hence - * scale will need to be applied if standard units required. - */ -int iio_st_read_channel_raw(struct iio_channel *chan, - int *val); - -/** - * iio_st_get_channel_type() - get the type of a channel - * @channel: The channel being queried. - * @type: The type of the channel. - * - * returns the enum iio_chan_type of the channel - */ -int iio_st_get_channel_type(struct iio_channel *channel, - enum iio_chan_type *type); - -/** - * iio_st_read_channel_scale() - read the scale value for a channel - * @channel: The channel being queried. - * @val: First part of value read back. - * @val2: Second part of value read back. - * - * Note returns a description of what is in val and val2, such - * as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val - * + val2/1e6 - */ -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, - int *val2); - -#endif diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index a57803a..a626f03 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -56,12 +56,12 @@ config AD5624R_SPI AD5664R converters (DAC). This driver uses the common SPI interface. config AD5446 - tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5542A/12A DAC SPI driver" + tristate "Analog Devices AD5446 and similar single channel DACs driver" depends on SPI help Say yes here to build support for Analog Devices AD5444, AD5446, - AD5512A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, AD5621, - AD5640, AD5660, AD5662 DACs. + AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5611, AD5620, + AD5621, AD5640, AD5660, AD5662 DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/staging/iio/dac/ad5064.c b/drivers/staging/iio/dac/ad5064.c index 06b1627..047148a 100644 --- a/drivers/staging/iio/dac/ad5064.c +++ b/drivers/staging/iio/dac/ad5064.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #define AD5064_MAX_DAC_CHANNELS 8 @@ -144,14 +144,14 @@ static const char ad5064_powerdown_modes[][15] = { }; static ssize_t ad5064_read_powerdown_mode_available(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { return sprintf(buf, "%s %s %s\n", ad5064_powerdown_modes[1], ad5064_powerdown_modes[2], ad5064_powerdown_modes[3]); } static ssize_t ad5064_read_powerdown_mode(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { struct ad5064_state *st = iio_priv(indio_dev); @@ -160,7 +160,8 @@ static ssize_t ad5064_read_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5064_write_powerdown_mode(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, const char *buf, size_t len) + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { struct ad5064_state *st = iio_priv(indio_dev); unsigned int mode, i; @@ -187,7 +188,7 @@ static ssize_t ad5064_write_powerdown_mode(struct iio_dev *indio_dev, } static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, char *buf) + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { struct ad5064_state *st = iio_priv(indio_dev); @@ -195,7 +196,8 @@ static ssize_t ad5064_read_dac_powerdown(struct iio_dev *indio_dev, } static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, const char *buf, size_t len) + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, + size_t len) { struct ad5064_state *st = iio_priv(indio_dev); bool pwr_down; @@ -235,7 +237,7 @@ static int ad5064_read_raw(struct iio_dev *indio_dev, int scale_uv; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: *val = st->dac_cache[chan->channel]; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -260,7 +262,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val > (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; @@ -308,7 +310,8 @@ static struct iio_chan_spec_ext_info ad5064_ext_info[] = { .indexed = 1, \ .output = 1, \ .channel = (chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = AD5064_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ .ext_info = ad5064_ext_info, \ @@ -442,7 +445,7 @@ static int __devinit ad5064_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -499,7 +502,7 @@ error_free_reg: if (!st->use_internal_vref) regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -517,7 +520,7 @@ static int __devexit ad5064_remove(struct spi_device *spi) regulator_bulk_free(ad5064_num_vref(st), st->vref_reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c index cec3693..38660ef 100644 --- a/drivers/staging/iio/dac/ad5360.c +++ b/drivers/staging/iio/dac/ad5360.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #define AD5360_CMD(x) ((x) << 22) @@ -103,7 +103,8 @@ enum ad5360_type { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ @@ -250,7 +251,7 @@ static ssize_t ad5360_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5360_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", (bool)(st->ctrl & AD5360_SF_CTRL_PWR_DOWN)); @@ -278,7 +279,7 @@ static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set, static ssize_t ad5360_write_dac_powerdown(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); bool pwr_down; int ret; @@ -319,7 +320,7 @@ static int ad5360_write_raw(struct iio_dev *indio_dev, unsigned int ofs_index; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; @@ -376,7 +377,7 @@ static int ad5360_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5360_read(indio_dev, AD5360_READBACK_X1A, chan->address); if (ret < 0) @@ -464,7 +465,7 @@ static int __devinit ad5360_probe(struct spi_device *spi) unsigned int i; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -519,7 +520,7 @@ error_free_reg: error_free_channels: kfree(indio_dev->channels); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -536,7 +537,7 @@ static int __devexit ad5360_remove(struct spi_device *spi) regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg); regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c index 4c50716..370d284 100644 --- a/drivers/staging/iio/dac/ad5380.c +++ b/drivers/staging/iio/dac/ad5380.c @@ -18,8 +18,8 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" @@ -85,7 +85,8 @@ enum ad5380_type { .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)) \ @@ -167,7 +168,7 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { static ssize_t ad5380_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); @@ -176,7 +177,7 @@ static ssize_t ad5380_read_dac_powerdown(struct device *dev, static ssize_t ad5380_write_dac_powerdown(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); bool pwr_down; int ret; @@ -212,7 +213,7 @@ static const char ad5380_powerdown_modes[][15] = { static ssize_t ad5380_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); unsigned int mode; int ret; @@ -229,7 +230,7 @@ static ssize_t ad5380_read_powerdown_mode(struct device *dev, static ssize_t ad5380_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5380_state *st = iio_priv(indio_dev); unsigned int i; int ret; @@ -292,7 +293,7 @@ static int ad5380_write_raw(struct iio_dev *indio_dev, struct ad5380_state *st = iio_priv(indio_dev); switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_CALIBSCALE: if (val >= max_val || val < 0) return -EINVAL; @@ -322,7 +323,7 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, int ret; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_CALIBSCALE: ret = regmap_read(st->regmap, ad5380_info_to_reg(chan, info), val); @@ -388,7 +389,7 @@ static int __devinit ad5380_probe(struct device *dev, struct regmap *regmap, unsigned int ctrl = 0; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(dev, "Failed to allocate iio device\n"); ret = -ENOMEM; @@ -454,7 +455,7 @@ error_free_reg: kfree(indio_dev->channels); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_regmap_exit: regmap_exit(regmap); @@ -476,7 +477,7 @@ static int __devexit ad5380_remove(struct device *dev) } regmap_exit(st->regmap); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5421.c b/drivers/staging/iio/dac/ad5421.c index 0b040b2..ffbd4c2 100644 --- a/drivers/staging/iio/dac/ad5421.c +++ b/drivers/staging/iio/dac/ad5421.c @@ -16,9 +16,9 @@ #include <linux/slab.h> #include <linux/sysfs.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include "dac.h" #include "ad5421.h" @@ -87,7 +87,8 @@ static const struct iio_chan_spec ad5421_channels[] = { .indexed = 1, .output = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_OFFSET_SHARED_BIT | IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, @@ -304,7 +305,7 @@ static int ad5421_read_raw(struct iio_dev *indio_dev, return -EINVAL; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA); if (ret < 0) return ret; @@ -340,7 +341,7 @@ static int ad5421_write_raw(struct iio_dev *indio_dev, const unsigned int max_val = 1 << 16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; @@ -456,7 +457,7 @@ static int __devinit ad5421_probe(struct spi_device *spi) struct ad5421_state *st; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -511,7 +512,7 @@ error_free_irq: if (spi->irq) free_irq(spi->irq, indio_dev); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -523,7 +524,7 @@ static int __devexit ad5421_remove(struct spi_device *spi) iio_device_unregister(indio_dev); if (spi->irq) free_irq(spi->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 633ffbb..daa65b3 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -18,229 +18,212 @@ #include <linux/err.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #include "ad5446.h" -static void ad5446_store_sample(struct ad5446_state *st, unsigned val) +static int ad5446_write(struct ad5446_state *st, unsigned val) { - st->data.d16 = cpu_to_be16(AD5446_LOAD | val); + __be16 data = cpu_to_be16(val); + return spi_write(st->spi, &data, sizeof(data)); } -static void ad5542_store_sample(struct ad5446_state *st, unsigned val) +static int ad5660_write(struct ad5446_state *st, unsigned val) { - st->data.d16 = cpu_to_be16(val); -} + uint8_t data[3]; -static void ad5620_store_sample(struct ad5446_state *st, unsigned val) -{ - st->data.d16 = cpu_to_be16(AD5620_LOAD | val); -} + data[0] = (val >> 16) & 0xFF; + data[1] = (val >> 8) & 0xFF; + data[2] = val & 0xFF; -static void ad5660_store_sample(struct ad5446_state *st, unsigned val) -{ - val |= AD5660_LOAD; - st->data.d24[0] = (val >> 16) & 0xFF; - st->data.d24[1] = (val >> 8) & 0xFF; - st->data.d24[2] = val & 0xFF; + return spi_write(st->spi, data, sizeof(data)); } -static void ad5620_store_pwr_down(struct ad5446_state *st, unsigned mode) -{ - st->data.d16 = cpu_to_be16(mode << 14); -} +static const char * const ad5446_powerdown_modes[] = { + "", "1kohm_to_gnd", "100kohm_to_gnd", "three_state" +}; -static void ad5660_store_pwr_down(struct ad5446_state *st, unsigned mode) +static ssize_t ad5446_read_powerdown_mode_available(struct iio_dev *indio_dev, + uintptr_t private, const struct iio_chan_spec *chan, char *buf) { - unsigned val = mode << 16; - - st->data.d24[0] = (val >> 16) & 0xFF; - st->data.d24[1] = (val >> 8) & 0xFF; - st->data.d24[2] = val & 0xFF; + return sprintf(buf, "%s %s %s\n", ad5446_powerdown_modes[1], + ad5446_powerdown_modes[2], ad5446_powerdown_modes[3]); } -static ssize_t ad5446_write_powerdown_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) +static ssize_t ad5446_write_powerdown_mode(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); + int i; - if (sysfs_streq(buf, "1kohm_to_gnd")) - st->pwr_down_mode = MODE_PWRDWN_1k; - else if (sysfs_streq(buf, "100kohm_to_gnd")) - st->pwr_down_mode = MODE_PWRDWN_100k; - else if (sysfs_streq(buf, "three_state")) - st->pwr_down_mode = MODE_PWRDWN_TRISTATE; - else + for (i = 1; i < ARRAY_SIZE(ad5446_powerdown_modes); i++) { + if (sysfs_streq(buf, ad5446_powerdown_modes[i])) { + st->pwr_down_mode = i; + break; + } + } + + if (i == ARRAY_SIZE(ad5446_powerdown_modes)) return -EINVAL; return len; } -static ssize_t ad5446_read_powerdown_mode(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t ad5446_read_powerdown_mode(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); - char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; - - return sprintf(buf, "%s\n", mode[st->pwr_down_mode]); + return sprintf(buf, "%s\n", ad5446_powerdown_modes[st->pwr_down_mode]); } -static ssize_t ad5446_read_dac_powerdown(struct device *dev, - struct device_attribute *attr, +static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); } -static ssize_t ad5446_write_dac_powerdown(struct device *dev, - struct device_attribute *attr, +static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5446_state *st = iio_priv(indio_dev); - unsigned long readin; + unsigned int shift; + unsigned int val; + bool powerdown; int ret; - ret = strict_strtol(buf, 10, &readin); + ret = strtobool(buf, &powerdown); if (ret) return ret; - if (readin > 1) - ret = -EINVAL; - mutex_lock(&indio_dev->mlock); - st->pwr_down = readin; + st->pwr_down = powerdown; - if (st->pwr_down) - st->chip_info->store_pwr_down(st, st->pwr_down_mode); - else - st->chip_info->store_sample(st, st->cached_val); + if (st->pwr_down) { + shift = chan->scan_type.realbits + chan->scan_type.shift; + val = st->pwr_down_mode << shift; + } else { + val = st->cached_val; + } - ret = spi_sync(st->spi, &st->msg); + ret = st->chip_info->write(st, val); mutex_unlock(&indio_dev->mlock); return ret ? ret : len; } -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, S_IRUGO | S_IWUSR, - ad5446_read_powerdown_mode, - ad5446_write_powerdown_mode, 0); - -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, - "1kohm_to_gnd 100kohm_to_gnd three_state"); - -static IIO_DEVICE_ATTR(out_voltage0_powerdown, S_IRUGO | S_IWUSR, - ad5446_read_dac_powerdown, - ad5446_write_dac_powerdown, 0); - -static struct attribute *ad5446_attributes[] = { - &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr, - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5446_attribute_group = { - .attrs = ad5446_attributes, +static const struct iio_chan_spec_ext_info ad5064_ext_info_powerdown[] = { + { + .name = "powerdown", + .read = ad5446_read_dac_powerdown, + .write = ad5446_write_dac_powerdown, + }, { + .name = "powerdown_mode", + .read = ad5446_read_powerdown_mode, + .write = ad5446_write_powerdown_mode, + }, { + .name = "powerdown_mode_available", + .shared = true, + .read = ad5446_read_powerdown_mode_available, + }, + { }, }; -#define AD5446_CHANNEL(bits, storage, shift) { \ +#define _AD5446_CHANNEL(bits, storage, shift, ext) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .scan_type = IIO_ST('u', (bits), (storage), (shift)) \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .scan_type = IIO_ST('u', (bits), (storage), (shift)), \ + .ext_info = (ext), \ } +#define AD5446_CHANNEL(bits, storage, shift) \ + _AD5446_CHANNEL(bits, storage, shift, NULL) + +#define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ + _AD5446_CHANNEL(bits, storage, shift, ad5064_ext_info_powerdown) + static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { [ID_AD5444] = { .channel = AD5446_CHANNEL(12, 16, 2), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5446] = { .channel = AD5446_CHANNEL(14, 16, 0), - .store_sample = ad5446_store_sample, + .write = ad5446_write, }, [ID_AD5541A] = { .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, - }, - [ID_AD5542A] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, - }, - [ID_AD5543] = { - .channel = AD5446_CHANNEL(16, 16, 0), - .store_sample = ad5542_store_sample, + .write = ad5446_write, }, [ID_AD5512A] = { .channel = AD5446_CHANNEL(12, 16, 4), - .store_sample = ad5542_store_sample, + .write = ad5446_write, }, [ID_AD5553] = { .channel = AD5446_CHANNEL(14, 16, 0), - .store_sample = ad5542_store_sample, + .write = ad5446_write, }, [ID_AD5601] = { - .channel = AD5446_CHANNEL(8, 16, 6), - .store_sample = ad5542_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), + .write = ad5446_write, }, [ID_AD5611] = { - .channel = AD5446_CHANNEL(10, 16, 4), - .store_sample = ad5542_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), + .write = ad5446_write, }, [ID_AD5621] = { - .channel = AD5446_CHANNEL(12, 16, 2), - .store_sample = ad5542_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), + .write = ad5446_write, }, [ID_AD5620_2500] = { - .channel = AD5446_CHANNEL(12, 16, 2), + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 2500, - .store_sample = ad5620_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5620_1250] = { - .channel = AD5446_CHANNEL(12, 16, 2), + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), .int_vref_mv = 1250, - .store_sample = ad5620_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5640_2500] = { - .channel = AD5446_CHANNEL(14, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 2500, - .store_sample = ad5620_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5640_1250] = { - .channel = AD5446_CHANNEL(14, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), .int_vref_mv = 1250, - .store_sample = ad5620_store_sample, - .store_pwr_down = ad5620_store_pwr_down, + .write = ad5446_write, }, [ID_AD5660_2500] = { - .channel = AD5446_CHANNEL(16, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 2500, - .store_sample = ad5660_store_sample, - .store_pwr_down = ad5660_store_pwr_down, + .write = ad5660_write, }, [ID_AD5660_1250] = { - .channel = AD5446_CHANNEL(16, 16, 0), + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), .int_vref_mv = 1250, - .store_sample = ad5660_store_sample, - .store_pwr_down = ad5660_store_pwr_down, + .write = ad5660_write, + }, + [ID_AD5662] = { + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), + .write = ad5660_write, }, }; @@ -254,6 +237,9 @@ static int ad5446_read_raw(struct iio_dev *indio_dev, unsigned long scale_uv; switch (m) { + case IIO_CHAN_INFO_RAW: + *val = st->cached_val; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits; *val = scale_uv / 1000; @@ -271,18 +257,18 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, long mask) { struct ad5446_state *st = iio_priv(indio_dev); - int ret; + int ret = 0; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; val <<= chan->scan_type.shift; mutex_lock(&indio_dev->mlock); st->cached_val = val; - st->chip_info->store_sample(st, val); - ret = spi_sync(st->spi, &st->msg); + if (!st->pwr_down) + ret = st->chip_info->write(st, val); mutex_unlock(&indio_dev->mlock); break; default: @@ -295,13 +281,6 @@ static int ad5446_write_raw(struct iio_dev *indio_dev, static const struct iio_info ad5446_info = { .read_raw = ad5446_read_raw, .write_raw = ad5446_write_raw, - .attrs = &ad5446_attribute_group, - .driver_module = THIS_MODULE, -}; - -static const struct iio_info ad5446_info_no_pwr_down = { - .read_raw = ad5446_read_raw, - .write_raw = ad5446_write_raw, .driver_module = THIS_MODULE, }; @@ -321,7 +300,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) voltage_uv = regulator_get_voltage(reg); } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -337,38 +316,17 @@ static int __devinit ad5446_probe(struct spi_device *spi) /* Establish that the iio_dev is a child of the spi device */ indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; - if (st->chip_info->store_pwr_down) - indio_dev->info = &ad5446_info; - else - indio_dev->info = &ad5446_info_no_pwr_down; + indio_dev->info = &ad5446_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = &st->chip_info->channel; indio_dev->num_channels = 1; - /* Setup default message */ - - st->xfer.tx_buf = &st->data; - st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8; - - spi_message_init(&st->msg); - spi_message_add_tail(&st->xfer, &st->msg); - - switch (spi_get_device_id(spi)->driver_data) { - case ID_AD5620_2500: - case ID_AD5620_1250: - case ID_AD5640_2500: - case ID_AD5640_1250: - case ID_AD5660_2500: - case ID_AD5660_1250: + if (st->chip_info->int_vref_mv) st->vref_mv = st->chip_info->int_vref_mv; - break; - default: - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, - "reference voltage unspecified\n"); - } + else if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); ret = iio_device_register(indio_dev); if (ret) @@ -377,7 +335,7 @@ static int __devinit ad5446_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -398,7 +356,7 @@ static int ad5446_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } @@ -408,8 +366,8 @@ static const struct spi_device_id ad5446_id[] = { {"ad5446", ID_AD5446}, {"ad5512a", ID_AD5512A}, {"ad5541a", ID_AD5541A}, - {"ad5542a", ID_AD5542A}, - {"ad5543", ID_AD5543}, + {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */ + {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */ {"ad5553", ID_AD5553}, {"ad5601", ID_AD5601}, {"ad5611", ID_AD5611}, @@ -420,6 +378,7 @@ static const struct spi_device_id ad5446_id[] = { {"ad5640-1250", ID_AD5640_1250}, {"ad5660-2500", ID_AD5660_2500}, {"ad5660-1250", ID_AD5660_1250}, + {"ad5662", ID_AD5662}, {} }; MODULE_DEVICE_TABLE(spi, ad5446_id); diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 4ea3476..dfd68ce 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -34,43 +34,30 @@ * @spi: spi_device * @chip_info: chip model specific constants, available modes etc * @reg: supply regulator - * @poll_work: bottom half of polling interrupt handler * @vref_mv: actual reference voltage used - * @xfer: default spi transfer - * @msg: default spi message - * @data: spi transmit buffer */ struct ad5446_state { struct spi_device *spi; const struct ad5446_chip_info *chip_info; struct regulator *reg; - struct work_struct poll_work; unsigned short vref_mv; unsigned cached_val; unsigned pwr_down_mode; unsigned pwr_down; - struct spi_transfer xfer; - struct spi_message msg; - union { - unsigned short d16; - unsigned char d24[3]; - } data; }; /** * struct ad5446_chip_info - chip specific information * @channel: channel spec for the DAC * @int_vref_mv: AD5620/40/60: the internal reference voltage - * @store_sample: chip specific helper function to store the datum - * @store_sample: chip specific helper function to store the powerpown cmd + * @write: chip specific helper function to write to the register */ struct ad5446_chip_info { struct iio_chan_spec channel; u16 int_vref_mv; - void (*store_sample) (struct ad5446_state *st, unsigned val); - void (*store_pwr_down) (struct ad5446_state *st, unsigned mode); + int (*write)(struct ad5446_state *st, unsigned val); }; /** @@ -85,8 +72,6 @@ enum ad5446_supported_device_ids { ID_AD5444, ID_AD5446, ID_AD5541A, - ID_AD5542A, - ID_AD5543, ID_AD5512A, ID_AD5553, ID_AD5601, @@ -98,6 +83,7 @@ enum ad5446_supported_device_ids { ID_AD5640_1250, ID_AD5660_2500, ID_AD5660_1250, + ID_AD5662, }; #endif /* IIO_DAC_AD5446_H_ */ diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index bc17205..019cf15 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -16,9 +16,9 @@ #include <linux/regulator/consumer.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include "dac.h" #include "ad5504.h" @@ -27,7 +27,8 @@ .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = AD5504_ADDR_DAC(_chan), \ .scan_type = IIO_ST('u', 12, 16, 0), \ } @@ -81,7 +82,7 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5504_spi_read(st->spi, chan->address); if (ret < 0) return ret; @@ -109,7 +110,7 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; @@ -124,7 +125,7 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, static ssize_t ad5504_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); const char mode[][14] = {"20kohm_to_gnd", "three_state"}; @@ -136,7 +137,7 @@ static ssize_t ad5504_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); int ret; @@ -154,7 +155,7 @@ static ssize_t ad5504_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -168,7 +169,7 @@ static ssize_t ad5504_write_dac_powerdown(struct device *dev, { long readin; int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -287,7 +288,7 @@ static int __devinit ad5504_probe(struct spi_device *spi) struct regulator *reg; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -350,7 +351,7 @@ error_put_reg: if (!IS_ERR(reg)) regulator_put(reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -368,7 +369,7 @@ static int __devexit ad5504_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 10c7484..42ff644 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -16,8 +16,8 @@ #include <linux/regulator/consumer.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #include "ad5624r.h" @@ -26,7 +26,8 @@ .indexed = 1, \ .output = 1, \ .channel = (_chan), \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = (_chan), \ .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ } @@ -122,7 +123,7 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; @@ -140,7 +141,7 @@ static int ad5624r_write_raw(struct iio_dev *indio_dev, static ssize_t ad5624r_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; @@ -152,7 +153,7 @@ static ssize_t ad5624r_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); int ret; @@ -172,7 +173,7 @@ static ssize_t ad5624r_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -186,7 +187,7 @@ static ssize_t ad5624r_write_dac_powerdown(struct device *dev, { long readin; int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5624r_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -255,7 +256,7 @@ static int __devinit ad5624r_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -305,7 +306,7 @@ error_disable_reg: error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -321,7 +322,7 @@ static int __devexit ad5624r_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index 2415a6e..c1e903e 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #define AD5686_DAC_CHANNELS 4 @@ -98,7 +98,8 @@ enum ad5686_supported_device_ids { .indexed = 1, \ .output = 1, \ .channel = chan, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = AD5686_ADDR_DAC(chan), \ .scan_type = IIO_ST('u', bits, 16, shift) \ } @@ -172,7 +173,7 @@ static int ad5686_spi_read(struct ad5686_state *st, u8 addr) static ssize_t ad5686_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -186,7 +187,7 @@ static ssize_t ad5686_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned mode; @@ -210,7 +211,7 @@ static ssize_t ad5686_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -224,7 +225,7 @@ static ssize_t ad5686_write_dac_powerdown(struct device *dev, { bool readin; int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5686_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -296,7 +297,7 @@ static int ad5686_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = ad5686_spi_read(st, chan->address); mutex_unlock(&indio_dev->mlock); @@ -326,7 +327,7 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (val > (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; @@ -358,7 +359,7 @@ static int __devinit ad5686_probe(struct spi_device *spi) struct iio_dev *indio_dev; int ret, regdone = 0, voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -410,7 +411,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -425,7 +426,7 @@ static int __devexit ad5686_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5764.c b/drivers/staging/iio/dac/ad5764.c index f73a730..03dbd93 100644 --- a/drivers/staging/iio/dac/ad5764.c +++ b/drivers/staging/iio/dac/ad5764.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/regulator/consumer.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #define AD5764_REG_SF_NOP 0x0 @@ -79,7 +79,8 @@ enum ad5764_type { .output = 1, \ .channel = (_chan), \ .address = (_chan), \ - .info_mask = IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SHARED_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ @@ -188,7 +189,7 @@ static int ad5764_write_raw(struct iio_dev *indio_dev, unsigned int reg; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: if (val >= max_val || val < 0) return -EINVAL; val <<= chan->scan_type.shift; @@ -228,7 +229,7 @@ static int ad5764_read_raw(struct iio_dev *indio_dev, int ret; switch (info) { - case 0: + case IIO_CHAN_INFO_RAW: reg = AD5764_REG_DATA(chan->address); ret = ad5764_read(indio_dev, reg, val); if (ret < 0) @@ -280,7 +281,7 @@ static int __devinit ad5764_probe(struct spi_device *spi) struct ad5764_state *st; int ret; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { dev_err(&spi->dev, "Failed to allocate iio device\n"); return -ENOMEM; @@ -335,7 +336,7 @@ error_free_reg: if (st->chip_info->int_vref == 0) regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); error_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -352,7 +353,7 @@ static int __devexit ad5764_remove(struct spi_device *spi) regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index ac45636..13d8b5b 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -17,8 +17,8 @@ #include <linux/regulator/consumer.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #include "ad5791.h" @@ -78,7 +78,8 @@ static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) .indexed = 1, \ .address = AD5791_ADDR_DAC0, \ .channel = 0, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ .scan_type = IIO_ST('u', bits, 24, shift) \ } @@ -93,7 +94,7 @@ static const struct iio_chan_spec ad5791_channels[] = { static ssize_t ad5791_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); const char mode[][14] = {"6kohm_to_gnd", "three_state"}; @@ -105,7 +106,7 @@ static ssize_t ad5791_write_powerdown_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); int ret; @@ -123,7 +124,7 @@ static ssize_t ad5791_read_dac_powerdown(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); @@ -135,7 +136,7 @@ static ssize_t ad5791_write_dac_powerdown(struct device *dev, { long readin; int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5791_state *st = iio_priv(indio_dev); ret = strict_strtol(buf, 10, &readin); @@ -231,7 +232,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, int ret; switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: ret = ad5791_spi_read(st->spi, chan->address, val); if (ret) return ret; @@ -263,7 +264,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, struct ad5791_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: val &= AD5791_RES_MASK(chan->scan_type.realbits); val <<= chan->scan_type.shift; @@ -288,7 +289,7 @@ static int __devinit ad5791_probe(struct spi_device *spi) struct ad5791_state *st; int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -368,7 +369,7 @@ error_put_reg_neg: error_put_reg_pos: if (!IS_ERR(st->reg_vdd)) regulator_put(st->reg_vdd); - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -389,7 +390,7 @@ static int __devexit ad5791_remove(struct spi_device *spi) regulator_disable(st->reg_vss); regulator_put(st->reg_vss); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 41483c7..5287cad 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -25,8 +25,8 @@ #include <linux/i2c.h> #include <linux/err.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dac.h" #include "max517.h" @@ -59,7 +59,7 @@ static ssize_t max517_set_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, int channel) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct max517_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; u8 outbuf[4]; /* 1x or 2x command + value */ @@ -128,7 +128,7 @@ static ssize_t max517_show_scale(struct device *dev, struct device_attribute *attr, char *buf, int channel) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct max517_data *data = iio_priv(indio_dev); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8; @@ -218,7 +218,7 @@ static int max517_probe(struct i2c_client *client, struct max517_platform_data *platform_data = client->dev.platform_data; int err; - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit; @@ -257,14 +257,15 @@ static int max517_probe(struct i2c_client *client, return 0; exit_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } static int max517_remove(struct i2c_client *client) { - iio_free_device(i2c_get_clientdata(client)); + iio_device_unregister(i2c_get_clientdata(client)); + iio_device_free(i2c_get_clientdata(client)); return 0; } diff --git a/drivers/staging/iio/dds/dds.h b/drivers/staging/iio/dds/dds.h deleted file mode 100644 index d8ac3a9..0000000 --- a/drivers/staging/iio/dds/dds.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * dds.h - sysfs attributes associated with DDS devices - * - * Copyright (c) 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -/** - * /sys/bus/iio/devices/.../ddsX_freqY - */ - -#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \ - _mode, _show, _store, _addr) - -/** - * /sys/bus/iio/devices/.../ddsX_freqY_scale - */ - -#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_freq_scale, _string) - -/** - * /sys/bus/iio/devices/.../ddsX_freqsymbol - */ - -#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_phaseY - */ - -#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \ - _mode, _show, _store, _addr) - -/** - * /sys/bus/iio/devices/.../ddsX_phaseY_scale - */ - -#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ - IIO_CONST_ATTR(dds##_channel##_phase_scale, _string) - -/** - * /sys/bus/iio/devices/.../ddsX_phasesymbol - */ - -#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en - */ - -#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ - IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_out_enable - */ - -#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out_enable, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_enable - */ - -#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ - _mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \ - _mode, _show, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype - */ - -#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ - IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \ - S_IWUSR, NULL, _store, _addr); - -/** - * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available - */ - -#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ - IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\ - _modes); diff --git a/drivers/staging/iio/driver.h b/drivers/staging/iio/driver.h deleted file mode 100644 index a4f8b2e..0000000 --- a/drivers/staging/iio/driver.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Industrial I/O in kernel access map interface. - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_INKERN_H_ -#define _IIO_INKERN_H_ - -struct iio_map; - -/** - * iio_map_array_register() - tell the core about inkernel consumers - * @indio_dev: provider device - * @map: array of mappings specifying association of channel with client - */ -int iio_map_array_register(struct iio_dev *indio_dev, - struct iio_map *map); - -/** - * iio_map_array_unregister() - tell the core to remove consumer mappings - * @indio_dev: provider device - * @map: array of mappings to remove. Note these must have same memory - * addresses as those originally added not just equal parameter - * values. - */ -int iio_map_array_unregister(struct iio_dev *indio_dev, - struct iio_map *map); - -#endif diff --git a/drivers/staging/iio/events.h b/drivers/staging/iio/events.h deleted file mode 100644 index c25f0e3..0000000 --- a/drivers/staging/iio/events.h +++ /dev/null @@ -1,105 +0,0 @@ -/* The industrial I/O - event passing to userspace - * - * Copyright (c) 2008-2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _IIO_EVENTS_H_ -#define _IIO_EVENTS_H_ - -#include <linux/ioctl.h> -#include <linux/types.h> -#include "types.h" - -/** - * struct iio_event_data - The actual event being pushed to userspace - * @id: event identifier - * @timestamp: best estimate of time of event occurrence (often from - * the interrupt handler) - */ -struct iio_event_data { - __u64 id; - __s64 timestamp; -}; - -#define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int) - -enum iio_event_type { - IIO_EV_TYPE_THRESH, - IIO_EV_TYPE_MAG, - IIO_EV_TYPE_ROC, - IIO_EV_TYPE_THRESH_ADAPTIVE, - IIO_EV_TYPE_MAG_ADAPTIVE, -}; - -enum iio_event_direction { - IIO_EV_DIR_EITHER, - IIO_EV_DIR_RISING, - IIO_EV_DIR_FALLING, -}; - -/** - * IIO_EVENT_CODE() - create event identifier - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @diff: Whether the event is for an differential channel or not. - * @modifier: Modifier for the channel. Should be one of enum iio_modifier. - * @direction: Direction of the event. One of enum iio_event_direction. - * @type: Type of the event. Should be one enum iio_event_type. - * @chan: Channel number for non-differential channels. - * @chan1: First channel number for differential channels. - * @chan2: Second channel number for differential channels. - */ - -#define IIO_EVENT_CODE(chan_type, diff, modifier, direction, \ - type, chan, chan1, chan2) \ - (((u64)type << 56) | ((u64)diff << 55) | \ - ((u64)direction << 48) | ((u64)modifier << 40) | \ - ((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \ - ((u16)chan)) - - -#define IIO_EV_DIR_MAX 4 -#define IIO_EV_BIT(type, direction) \ - (1 << (type*IIO_EV_DIR_MAX + direction)) - -/** - * IIO_MOD_EVENT_CODE() - create event identifier for modified channels - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @number: Channel number. - * @modifier: Modifier for the channel. Should be one of enum iio_modifier. - * @type: Type of the event. Should be one enum iio_event_type. - * @direction: Direction of the event. One of enum iio_event_direction. - */ - -#define IIO_MOD_EVENT_CODE(chan_type, number, modifier, \ - type, direction) \ - IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0) - -/** - * IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified channels - * @chan_type: Type of the channel. Should be one of enum iio_chan_type. - * @number: Channel number. - * @type: Type of the event. Should be one enum iio_event_type. - * @direction: Direction of the event. One of enum iio_event_direction. - */ - -#define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \ - IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0) - -#define IIO_EVENT_CODE_EXTRACT_TYPE(mask) ((mask >> 56) & 0xFF) - -#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 48) & 0xCF) - -#define IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(mask) ((mask >> 32) & 0xFF) - -/* Event code number extraction depends on which type of event we have. - * Perhaps review this function in the future*/ -#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF)) -#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF)) - -#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF) -#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1) - -#endif diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/frequency/Kconfig index 93b7141..93b7141 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/frequency/Kconfig diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/frequency/Makefile index 1477461..1477461 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/frequency/Makefile diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/frequency/ad5930.c index 9c32d1b..2d541d0 100644 --- a/drivers/staging/iio/dds/ad5930.c +++ b/drivers/staging/iio/frequency/ad5930.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad5930" @@ -48,7 +48,7 @@ static ssize_t ad5930_set_parameter(struct device *dev, struct spi_transfer xfer; int ret; struct ad5903_config *config = (struct ad5903_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); + struct iio_dev *idev = dev_to_iio_dev(dev); struct ad5930_state *st = iio_priv(idev); config->control = (config->control & ~value_mask); @@ -97,7 +97,7 @@ static int __devinit ad5930_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -122,7 +122,7 @@ static int __devinit ad5930_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -130,7 +130,7 @@ error_ret: static int __devexit ad5930_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 2ccf25d..fed3940 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -16,8 +16,8 @@ #include <linux/module.h> #include <asm/div64.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dds.h" #include "ad9832.h" @@ -77,7 +77,7 @@ static ssize_t ad9832_write(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad9832_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -177,18 +177,18 @@ static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9832_write, AD9832_OUTPUT_EN); static struct attribute *ad9832_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_dev_attr_dds0_phase2.dev_attr.attr, - &iio_dev_attr_dds0_phase3.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase2.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase3.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, NULL, }; @@ -221,7 +221,7 @@ static int __devinit ad9832_probe(struct spi_device *spi) goto error_put_reg; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -313,7 +313,7 @@ static int __devinit ad9832_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -334,7 +334,7 @@ static int __devexit ad9832_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dds/ad9832.h b/drivers/staging/iio/frequency/ad9832.h index c5b701f..c5b701f 100644 --- a/drivers/staging/iio/dds/ad9832.h +++ b/drivers/staging/iio/frequency/ad9832.h diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 38a2de0..1b2dc74 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c @@ -19,8 +19,8 @@ #include <linux/module.h> #include <asm/div64.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "dds.h" #include "ad9834.h" @@ -66,7 +66,7 @@ static ssize_t ad9834_write(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad9834_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -145,7 +145,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad9834_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret = 0; @@ -203,7 +203,7 @@ static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad9834_state *st = iio_priv(indio_dev); char *str; @@ -218,14 +218,14 @@ static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, } -static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO, +static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, S_IRUGO, ad9834_show_out0_wavetype_available, NULL, 0); static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad9834_state *st = iio_priv(indio_dev); char *str; @@ -237,7 +237,7 @@ static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, return sprintf(buf, "%s\n", str); } -static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO, +static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, S_IRUGO, ad9834_show_out1_wavetype_available, NULL, 0); /** @@ -263,36 +263,36 @@ static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); static struct attribute *ad9834_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out1_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, - &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out1_wavetype_available.dev_attr.attr, NULL, }; static struct attribute *ad9833_attributes[] = { - &iio_dev_attr_dds0_freq0.dev_attr.attr, - &iio_dev_attr_dds0_freq1.dev_attr.attr, - &iio_const_attr_dds0_freq_scale.dev_attr.attr, - &iio_dev_attr_dds0_phase0.dev_attr.attr, - &iio_dev_attr_dds0_phase1.dev_attr.attr, - &iio_const_attr_dds0_phase_scale.dev_attr.attr, - &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, - &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, - &iio_dev_attr_dds0_out_enable.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, - &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, + &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_out_altvoltage0_out0_wavetype_available.dev_attr.attr, NULL, }; @@ -334,7 +334,7 @@ static int __devinit ad9834_probe(struct spi_device *spi) goto error_put_reg; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; @@ -414,7 +414,7 @@ static int __devinit ad9834_probe(struct spi_device *spi) return 0; error_free_device: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_disable_reg: if (!IS_ERR(reg)) regulator_disable(reg); @@ -434,7 +434,7 @@ static int __devexit ad9834_remove(struct spi_device *spi) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/dds/ad9834.h b/drivers/staging/iio/frequency/ad9834.h index ed5ed8d..ed5ed8d 100644 --- a/drivers/staging/iio/dds/ad9834.h +++ b/drivers/staging/iio/frequency/ad9834.h diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/frequency/ad9850.c index f4f731b..74abee0 100644 --- a/drivers/staging/iio/dds/ad9850.c +++ b/drivers/staging/iio/frequency/ad9850.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad9850" @@ -43,7 +43,7 @@ static ssize_t ad9850_set_parameter(struct device *dev, struct spi_transfer xfer; int ret; struct ad9850_config *config = (struct ad9850_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); + struct iio_dev *idev = dev_to_iio_dev(dev); struct ad9850_state *st = iio_priv(idev); xfer.len = len; @@ -83,7 +83,7 @@ static int __devinit ad9850_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -108,7 +108,7 @@ static int __devinit ad9850_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -116,7 +116,7 @@ error_ret: static int __devexit ad9850_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/frequency/ad9852.c index 554266c..fd9d14a 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/frequency/ad9852.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad9852" @@ -71,7 +71,7 @@ static ssize_t ad9852_set_parameter(struct device *dev, struct spi_transfer xfer; int ret; struct ad9852_config *config = (struct ad9852_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); + struct iio_dev *idev = dev_to_iio_dev(dev); struct ad9852_state *st = iio_priv(idev); xfer.len = 3; @@ -232,7 +232,7 @@ static int __devinit ad9852_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -258,7 +258,7 @@ static int __devinit ad9852_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; @@ -267,7 +267,7 @@ error_ret: static int __devexit ad9852_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/frequency/ad9910.c index 3985766..5a7ba30 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/frequency/ad9910.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad9910" @@ -123,7 +123,7 @@ static ssize_t ad9910_set_parameter(struct device *dev, struct spi_transfer xfer; int ret; struct ad9910_config *config = (struct ad9910_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); + struct iio_dev *idev = dev_to_iio_dev(dev); struct ad9910_state *st = iio_priv(idev); xfer.len = 5; @@ -367,7 +367,7 @@ static int __devinit ad9910_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -392,7 +392,7 @@ static int __devinit ad9910_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; } @@ -400,7 +400,7 @@ error_ret: static int __devexit ad9910_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/frequency/ad9951.c index 4d15004..ba6f49f 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/frequency/ad9951.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad9951" @@ -64,7 +64,7 @@ static ssize_t ad9951_set_parameter(struct device *dev, struct spi_transfer xfer; int ret; struct ad9951_config *config = (struct ad9951_config *)buf; - struct iio_dev *idev = dev_get_drvdata(dev); + struct iio_dev *idev = dev_to_iio_dev(dev); struct ad9951_state *st = iio_priv(idev); xfer.len = 3; @@ -176,7 +176,7 @@ static int __devinit ad9951_probe(struct spi_device *spi) struct iio_dev *idev; int ret = 0; - idev = iio_allocate_device(sizeof(*st)); + idev = iio_device_alloc(sizeof(*st)); if (idev == NULL) { ret = -ENOMEM; goto error_ret; @@ -202,7 +202,7 @@ static int __devinit ad9951_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(idev); + iio_device_free(idev); error_ret: return ret; @@ -211,7 +211,7 @@ error_ret: static int __devexit ad9951_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/frequency/dds.h b/drivers/staging/iio/frequency/dds.h new file mode 100644 index 0000000..c3342f6 --- /dev/null +++ b/drivers/staging/iio/frequency/dds.h @@ -0,0 +1,110 @@ +/* + * dds.h - sysfs attributes associated with DDS devices + * + * Copyright (c) 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_frequencyY + */ + +#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_frequency##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_frequencyY_scale + */ + +#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ + IIO_CONST_ATTR(out_altvoltage##_channel##_frequency_scale, _string) + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_frequencysymbol + */ + +#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_frequencysymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_phaseY + */ + +#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_phase##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_phaseY_scale + */ + +#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ + IIO_CONST_ATTR(out_altvoltage##_channel##_phase_scale, _string) + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_phasesymbol + */ + +#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_phasesymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_frequency_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_frequency_en,\ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_pincontrol_phase_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_pincontrol_phase_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_out_enable + */ + +#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out_enable, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_outY_enable + */ + +#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ + _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_enable,\ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype + */ + +#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ + IIO_DEVICE_ATTR(out_altvoltage##_channel##_out##_output##_wavetype,\ + S_IWUSR, NULL, _store, _addr); + +/** + * /sys/bus/iio/devices/.../out_altvoltageX_outY_wavetype_available + */ + +#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ + IIO_CONST_ATTR( \ + out_altvoltage##_channel##_out##_output##_wavetype_available, _modes); diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 02cc234..9931e206 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -15,8 +15,8 @@ #include <linux/slab.h> #include <linux/sysfs.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ #define ADIS16060_TEMP_OUT 0x10 /* Measure Temperature */ @@ -85,7 +85,7 @@ static int adis16060_read_raw(struct iio_dev *indio_dev, int ret; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); ret = adis16060_spi_write(indio_dev, chan->address); @@ -120,22 +120,26 @@ static const struct iio_chan_spec adis16060_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16060_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = ADIS16060_TEMP_OUT, } @@ -148,7 +152,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -174,7 +178,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -183,7 +187,7 @@ error_ret: static int adis16060_r_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index 1815490..11f1dcc 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -14,8 +14,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ #define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ @@ -87,7 +87,7 @@ static int adis16080_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: ret = adis16080_spi_write(indio_dev, chan->address | ADIS16080_DIN_WRITE); @@ -110,21 +110,25 @@ static const struct iio_chan_spec adis16080_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_GYRO, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_AIN1, }, { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_AIN2, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16080_DIN_TEMP, } }; @@ -141,7 +145,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -167,7 +171,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -176,7 +180,7 @@ error_ret: static int adis16080_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 947eb86..bf61cd0 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -16,8 +16,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define ADIS16130_CON 0x0 #define ADIS16130_CON_RD (1 << 6) @@ -100,11 +100,13 @@ static const struct iio_chan_spec adis16130_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16130_RATEDATA, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .address = ADIS16130_TEMPDATA, } }; @@ -121,7 +123,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -145,7 +147,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -155,7 +157,7 @@ error_ret: static int adis16130_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 8f6af47..ec765f9 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -18,9 +18,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16260.h" @@ -149,7 +149,7 @@ static ssize_t adis16260_read_frequency_available(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16260_state *st = iio_priv(indio_dev); if (spi_get_device_id(st->us)->driver_data) return sprintf(buf, "%s\n", "0.129 ~ 256"); @@ -161,7 +161,7 @@ static ssize_t adis16260_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16260_state *st = iio_priv(indio_dev); int ret, len = 0; u16 t; @@ -186,7 +186,7 @@ static ssize_t adis16260_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16260_state *st = iio_priv(indio_dev); long val; int ret; @@ -237,7 +237,7 @@ static ssize_t adis16260_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); if (len < 1) return -EINVAL; switch (buf[0]) { @@ -389,30 +389,76 @@ enum adis16260_channel { }; #define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \ struct iio_chan_spec adis16260_channels_##axis[] = { \ - IIO_CHAN(IIO_ANGL_VEL, 1, 0, 0, NULL, 0, mod, \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - gyro, ADIS16260_SCAN_GYRO, \ - IIO_ST('s', 14, 16, 0), 0), \ - IIO_CHAN(IIO_ANGL, 1, 0, 0, NULL, 0, mod, \ - 0, \ - angle, ADIS16260_SCAN_ANGL, \ - IIO_ST('u', 14, 16, 0), 0), \ - IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - temp, ADIS16260_SCAN_TEMP, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "supply", 0, 0, \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - in_supply, ADIS16260_SCAN_SUPPLY, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - in_aux, ADIS16260_SCAN_AUX_ADC, \ - IIO_ST('u', 12, 16, 0), 0), \ - IIO_CHAN_SOFT_TIMESTAMP(5) \ + { \ + .type = IIO_ANGL_VEL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = gyro, \ + .scan_index = ADIS16260_SCAN_GYRO, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 14, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_ANGL, \ + .modified = 1, \ + .channel2 = mod, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .address = angle, \ + .scan_index = ADIS16260_SCAN_ANGL, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 14, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = temp, \ + .scan_index = ADIS16260_SCAN_TEMP, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = 0, \ + .extend_name = "supply", \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = in_supply, \ + .scan_index = ADIS16260_SCAN_SUPPLY, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = 1, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = in_aux, \ + .scan_index = ADIS16260_SCAN_AUX_ADC, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ + }, \ + IIO_CHAN_SOFT_TIMESTAMP(5), \ } static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X); @@ -440,7 +486,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); addr = adis16260_addresses[chan->address][0]; ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); @@ -581,7 +627,7 @@ static int __devinit adis16260_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -666,7 +712,7 @@ error_uninitialize_ring: error_unreg_ring_funcs: adis16260_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -687,7 +733,7 @@ static int adis16260_remove(struct spi_device *spi) adis16260_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16260_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index 711f151..0fe2d9d 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -5,20 +5,19 @@ #include <linux/spi/spi.h> #include <linux/slab.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16260.h" /** * adis16260_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read **/ -static int adis16260_read_ring_data(struct device *dev, u8 *rx) +static int adis16260_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16260_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16260_OUTPUTS + 1]; int ret; @@ -66,22 +65,21 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; } if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0) + adis16260_read_ring_data(indio_dev, st->rx) >= 0) for (; i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; ring->access->store_to(ring, (u8 *)data, pf->timestamp); diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c index 8299cd1..034559e 100644 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16260.h" /** @@ -29,7 +29,7 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16260_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->us)->name, indio_dev->id); if (st->trig == NULL) { @@ -60,7 +60,7 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -71,5 +71,5 @@ void adis16260_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h index af0c870..f8cf21f 100644 --- a/drivers/staging/iio/gyro/adxrs450.h +++ b/drivers/staging/iio/gyro/adxrs450.h @@ -49,7 +49,7 @@ enum { * @us: actual spi_device * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer - * @rx: recieve buffer + * @rx: receive buffer **/ struct adxrs450_state { struct spi_device *us; diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 15e2496..6513119 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -18,8 +18,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "adxrs450.h" @@ -265,7 +265,7 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev, s16 t; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: switch (chan->type) { case IIO_ANGL_VEL: ret = adxrs450_spi_sensor_data(indio_dev, &t); @@ -329,14 +329,16 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } }, [ID_ADXRS453] = { @@ -344,13 +346,15 @@ static const struct iio_chan_spec adxrs450_channels[2][2] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT, }, { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, } }, }; @@ -368,7 +372,7 @@ static int __devinit adxrs450_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -399,7 +403,7 @@ static int __devinit adxrs450_probe(struct spi_device *spi) error_initial: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -408,7 +412,7 @@ error_ret: static int adxrs450_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h deleted file mode 100644 index b9cd454..0000000 --- a/drivers/staging/iio/iio.h +++ /dev/null @@ -1,471 +0,0 @@ - -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#ifndef _INDUSTRIAL_IO_H_ -#define _INDUSTRIAL_IO_H_ - -#include <linux/device.h> -#include <linux/cdev.h> -#include "types.h" -/* IIO TODO LIST */ -/* - * Provide means of adjusting timer accuracy. - * Currently assumes nano seconds. - */ - -enum iio_data_type { - IIO_RAW, - IIO_PROCESSED, -}; - -/* Could add the raw attributes as well - allowing buffer only devices */ -enum iio_chan_info_enum { - /* 0 is reserved for raw attributes */ - IIO_CHAN_INFO_SCALE = 1, - IIO_CHAN_INFO_OFFSET, - IIO_CHAN_INFO_CALIBSCALE, - IIO_CHAN_INFO_CALIBBIAS, - IIO_CHAN_INFO_PEAK, - IIO_CHAN_INFO_PEAK_SCALE, - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, - IIO_CHAN_INFO_AVERAGE_RAW, - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, -}; - -#define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) -#define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) - -#define IIO_CHAN_INFO_SCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_SCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_SCALE) -#define IIO_CHAN_INFO_OFFSET_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_OFFSET_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_OFFSET) -#define IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBSCALE) -#define IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_CALIBBIAS_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_CALIBBIAS) -#define IIO_CHAN_INFO_PEAK_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAK_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAK) -#define IIO_CHAN_INFO_PEAKSCALE_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_PEAKSCALE_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_PEAKSCALE) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_AVERAGE_RAW_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_AVERAGE_RAW) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT \ - IIO_CHAN_INFO_SHARED_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) -#define IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT \ - IIO_CHAN_INFO_SEPARATE_BIT( \ - IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) - -enum iio_endian { - IIO_CPU, - IIO_BE, - IIO_LE, -}; - -struct iio_chan_spec; -struct iio_dev; - -/** - * struct iio_chan_spec_ext_info - Extended channel info attribute - * @name: Info attribute name - * @shared: Whether this attribute is shared between all channels. - * @read: Read callback for this info attribute, may be NULL. - * @write: Write callback for this info attribute, may be NULL. - */ -struct iio_chan_spec_ext_info { - const char *name; - bool shared; - ssize_t (*read)(struct iio_dev *, struct iio_chan_spec const *, - char *buf); - ssize_t (*write)(struct iio_dev *, struct iio_chan_spec const *, - const char *buf, size_t len); -}; - -/** - * struct iio_chan_spec - specification of a single channel - * @type: What type of measurement is the channel making. - * @channel: What number or name do we wish to assign the channel. - * @channel2: If there is a second number for a differential - * channel then this is it. If modified is set then the - * value here specifies the modifier. - * @address: Driver specific identifier. - * @scan_index: Monotonic index to give ordering in scans when read - * from a buffer. - * @scan_type: Sign: 's' or 'u' to specify signed or unsigned - * realbits: Number of valid bits of data - * storage_bits: Realbits + padding - * shift: Shift right by this before masking out - * realbits. - * endianness: little or big endian - * @info_mask: What information is to be exported about this channel. - * This includes calibbias, scale etc. - * @event_mask: What events can this channel produce. - * @ext_info: Array of extended info attributes for this channel. - * The array is NULL terminated, the last element should - * have it's name field set to NULL. - * @extend_name: Allows labeling of channel attributes with an - * informative name. Note this has no effect codes etc, - * unlike modifiers. - * @datasheet_name: A name used in in kernel mapping of channels. It should - * correspond to the first name that the channel is referred - * to by in the datasheet (e.g. IND), or the nearest - * possible compound name (e.g. IND-INC). - * @processed_val: Flag to specify the data access attribute should be - * *_input rather than *_raw. - * @modified: Does a modifier apply to this channel. What these are - * depends on the channel type. Modifier is set in - * channel2. Examples are IIO_MOD_X for axial sensors about - * the 'x' axis. - * @indexed: Specify the channel has a numerical index. If not, - * the value in channel will be suppressed for attribute - * but not for event codes. Typically set it to 0 when - * the index is false. - * @differential: Channel is differential. - */ -struct iio_chan_spec { - enum iio_chan_type type; - int channel; - int channel2; - unsigned long address; - int scan_index; - struct { - char sign; - u8 realbits; - u8 storagebits; - u8 shift; - enum iio_endian endianness; - } scan_type; - long info_mask; - long event_mask; - const struct iio_chan_spec_ext_info *ext_info; - char *extend_name; - const char *datasheet_name; - unsigned processed_val:1; - unsigned modified:1; - unsigned indexed:1; - unsigned output:1; - unsigned differential:1; -}; - -#define IIO_ST(si, rb, sb, sh) \ - { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } - -/* Macro assumes input channels */ -#define IIO_CHAN(_type, _mod, _indexed, _proc, _name, _chan, _chan2, \ - _inf_mask, _address, _si, _stype, _event_mask) \ - { .type = _type, \ - .output = 0, \ - .modified = _mod, \ - .indexed = _indexed, \ - .processed_val = _proc, \ - .extend_name = _name, \ - .channel = _chan, \ - .channel2 = _chan2, \ - .info_mask = _inf_mask, \ - .address = _address, \ - .scan_index = _si, \ - .scan_type = _stype, \ - .event_mask = _event_mask } - -#define IIO_CHAN_SOFT_TIMESTAMP(_si) \ - { .type = IIO_TIMESTAMP, .channel = -1, \ - .scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) } - -/** - * iio_get_time_ns() - utility function to get a time stamp for events etc - **/ -static inline s64 iio_get_time_ns(void) -{ - struct timespec ts; - /* - * calls getnstimeofday. - * If hrtimers then up to ns accurate, if not microsecond. - */ - ktime_get_real_ts(&ts); - - return timespec_to_ns(&ts); -} - -/* Device operating modes */ -#define INDIO_DIRECT_MODE 0x01 -#define INDIO_BUFFER_TRIGGERED 0x02 -#define INDIO_BUFFER_HARDWARE 0x08 - -#define INDIO_ALL_BUFFER_MODES \ - (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE) - -struct iio_trigger; /* forward declaration */ -struct iio_dev; - -/** - * struct iio_info - constant information about device - * @driver_module: module structure used to ensure correct - * ownership of chrdevs etc - * @event_attrs: event control attributes - * @attrs: general purpose device attributes - * @read_raw: function to request a value from the device. - * mask specifies which value. Note 0 means a reading of - * the channel in question. Return value will specify the - * type of value returned by the device. val and val2 will - * contain the elements making up the returned value. - * @write_raw: function to write a value to the device. - * Parameters are the same as for read_raw. - * @write_raw_get_fmt: callback function to query the expected - * format/precision. If not set by the driver, write_raw - * returns IIO_VAL_INT_PLUS_MICRO. - * @read_event_config: find out if the event is enabled. - * @write_event_config: set if the event is enabled. - * @read_event_value: read a value associated with the event. Meaning - * is event dependant. event_code specifies which event. - * @write_event_value: write the value associated with the event. - * Meaning is event dependent. - * @validate_trigger: function to validate the trigger when the - * current trigger gets changed. - **/ -struct iio_info { - struct module *driver_module; - struct attribute_group *event_attrs; - const struct attribute_group *attrs; - - int (*read_raw)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long mask); - - int (*write_raw)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask); - - int (*write_raw_get_fmt)(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - long mask); - - int (*read_event_config)(struct iio_dev *indio_dev, - u64 event_code); - - int (*write_event_config)(struct iio_dev *indio_dev, - u64 event_code, - int state); - - int (*read_event_value)(struct iio_dev *indio_dev, - u64 event_code, - int *val); - int (*write_event_value)(struct iio_dev *indio_dev, - u64 event_code, - int val); - int (*validate_trigger)(struct iio_dev *indio_dev, - struct iio_trigger *trig); - int (*update_scan_mode)(struct iio_dev *indio_dev, - const unsigned long *scan_mask); - int (*debugfs_reg_access)(struct iio_dev *indio_dev, - unsigned reg, unsigned writeval, - unsigned *readval); -}; - -/** - * struct iio_buffer_setup_ops - buffer setup related callbacks - * @preenable: [DRIVER] function to run prior to marking buffer enabled - * @postenable: [DRIVER] function to run after marking buffer enabled - * @predisable: [DRIVER] function to run prior to marking buffer - * disabled - * @postdisable: [DRIVER] function to run after marking buffer disabled - */ -struct iio_buffer_setup_ops { - int (*preenable)(struct iio_dev *); - int (*postenable)(struct iio_dev *); - int (*predisable)(struct iio_dev *); - int (*postdisable)(struct iio_dev *); -}; - -/** - * struct iio_dev - industrial I/O device - * @id: [INTERN] used to identify device internally - * @modes: [DRIVER] operating modes supported by device - * @currentmode: [DRIVER] current operating mode - * @dev: [DRIVER] device structure, should be assigned a parent - * and owner - * @event_interface: [INTERN] event chrdevs associated with interrupt lines - * @buffer: [DRIVER] any buffer present - * @mlock: [INTERN] lock used to prevent simultaneous device state - * changes - * @available_scan_masks: [DRIVER] optional array of allowed bitmasks - * @masklength: [INTERN] the length of the mask established from - * channels - * @active_scan_mask: [INTERN] union of all scan masks requested by buffers - * @trig: [INTERN] current device trigger (buffer modes) - * @pollfunc: [DRIVER] function run on trigger being received - * @channels: [DRIVER] channel specification structure table - * @num_channels: [DRIVER] number of chanels specified in @channels. - * @channel_attr_list: [INTERN] keep track of automatically created channel - * attributes - * @chan_attr_group: [INTERN] group for all attrs in base directory - * @name: [DRIVER] name of the device. - * @info: [DRIVER] callbacks and constant info from driver - * @info_exist_lock: [INTERN] lock to prevent use during removal - * @chrdev: [INTERN] associated character device - * @groups: [INTERN] attribute groups - * @groupcounter: [INTERN] index of next attribute group - * @flags: [INTERN] file ops related flags including busy flag. - * @debugfs_dentry: [INTERN] device specific debugfs dentry. - * @cached_reg_addr: [INTERN] cached register address for debugfs reads. - */ -struct iio_dev { - int id; - - int modes; - int currentmode; - struct device dev; - - struct iio_event_interface *event_interface; - - struct iio_buffer *buffer; - struct mutex mlock; - - const unsigned long *available_scan_masks; - unsigned masklength; - const unsigned long *active_scan_mask; - struct iio_trigger *trig; - struct iio_poll_func *pollfunc; - - struct iio_chan_spec const *channels; - int num_channels; - - struct list_head channel_attr_list; - struct attribute_group chan_attr_group; - const char *name; - const struct iio_info *info; - struct mutex info_exist_lock; - const struct iio_buffer_setup_ops *setup_ops; - struct cdev chrdev; -#define IIO_MAX_GROUPS 6 - const struct attribute_group *groups[IIO_MAX_GROUPS + 1]; - int groupcounter; - - unsigned long flags; -#if defined(CONFIG_DEBUG_FS) - struct dentry *debugfs_dentry; - unsigned cached_reg_addr; -#endif -}; - -/** - * iio_find_channel_from_si() - get channel from its scan index - * @indio_dev: device - * @si: scan index to match - */ -const struct iio_chan_spec -*iio_find_channel_from_si(struct iio_dev *indio_dev, int si); - -/** - * iio_device_register() - register a device with the IIO subsystem - * @indio_dev: Device structure filled by the device driver - **/ -int iio_device_register(struct iio_dev *indio_dev); - -/** - * iio_device_unregister() - unregister a device from the IIO subsystem - * @indio_dev: Device structure representing the device. - **/ -void iio_device_unregister(struct iio_dev *indio_dev); - -/** - * iio_push_event() - try to add event to the list for userspace reading - * @indio_dev: IIO device structure - * @ev_code: What event - * @timestamp: When the event occurred - **/ -int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); - -extern struct bus_type iio_bus_type; - -/** - * iio_put_device() - reference counted deallocation of struct device - * @dev: the iio_device containing the device - **/ -static inline void iio_put_device(struct iio_dev *indio_dev) -{ - if (indio_dev) - put_device(&indio_dev->dev); -}; - -/* Can we make this smaller? */ -#define IIO_ALIGN L1_CACHE_BYTES -/** - * iio_allocate_device() - allocate an iio_dev from a driver - * @sizeof_priv: Space to allocate for private structure. - **/ -struct iio_dev *iio_allocate_device(int sizeof_priv); - -static inline void *iio_priv(const struct iio_dev *indio_dev) -{ - return (char *)indio_dev + ALIGN(sizeof(struct iio_dev), IIO_ALIGN); -} - -static inline struct iio_dev *iio_priv_to_dev(void *priv) -{ - return (struct iio_dev *)((char *)priv - - ALIGN(sizeof(struct iio_dev), IIO_ALIGN)); -} - -/** - * iio_free_device() - free an iio_dev from a driver - * @dev: the iio_dev associated with the device - **/ -void iio_free_device(struct iio_dev *indio_dev); - -/** - * iio_buffer_enabled() - helper function to test if the buffer is enabled - * @indio_dev: IIO device info structure for device - **/ -static inline bool iio_buffer_enabled(struct iio_dev *indio_dev) -{ - return indio_dev->currentmode - & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE); -}; - -/** - * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry - * @indio_dev: IIO device info structure for device - **/ -#if defined(CONFIG_DEBUG_FS) -static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) -{ - return indio_dev->debugfs_dentry; -}; -#else -static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) -{ - return NULL; -}; -#endif - -#endif /* _INDUSTRIAL_IO_H_ */ diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h deleted file mode 100644 index c9dfcba..0000000 --- a/drivers/staging/iio/iio_core.h +++ /dev/null @@ -1,56 +0,0 @@ -/* The industrial I/O core function defs. - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * These definitions are meant for use only within the IIO core, not individual - * drivers. - */ - -#ifndef _IIO_CORE_H_ -#define _IIO_CORE_H_ - -int __iio_add_chan_devattr(const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*func)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - u64 mask, - bool generic, - struct device *dev, - struct list_head *attr_list); - -/* Event interface flags */ -#define IIO_BUSY_BIT_POS 1 - -#ifdef CONFIG_IIO_BUFFER -struct poll_table_struct; - -unsigned int iio_buffer_poll(struct file *filp, - struct poll_table_struct *wait); -ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps); - - -#define iio_buffer_poll_addr (&iio_buffer_poll) -#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer) - -#else - -#define iio_buffer_poll_addr NULL -#define iio_buffer_read_first_n_outer_addr NULL - -#endif - -int iio_device_register_eventset(struct iio_dev *indio_dev); -void iio_device_unregister_eventset(struct iio_dev *indio_dev); -int iio_event_getfd(struct iio_dev *indio_dev); - -#endif diff --git a/drivers/staging/iio/iio_core_trigger.h b/drivers/staging/iio/iio_core_trigger.h deleted file mode 100644 index 6f7c56f..0000000 --- a/drivers/staging/iio/iio_core_trigger.h +++ /dev/null @@ -1,46 +0,0 @@ - -/* The industrial I/O core, trigger consumer handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifdef CONFIG_IIO_TRIGGER -/** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @indio_dev: iio_dev associated with the device that will consume the trigger - **/ -void iio_device_register_trigger_consumer(struct iio_dev *indio_dev); - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @indio_dev: iio_dev associated with the device that consumed the trigger - **/ -void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev); - -#else - -/** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @indio_dev: iio_dev associated with the device that will consume the trigger - **/ -static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev) -{ - return 0; -}; - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @indio_dev: iio_dev associated with the device that consumed the trigger - **/ -static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) -{ -}; - -#endif /* CONFIG_TRIGGER_CONSUMER */ - - - diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index f39f346..0cd4fe9 100644 --- a/drivers/staging/iio/iio_dummy_evgen.c +++ b/drivers/staging/iio/iio_dummy_evgen.c @@ -22,8 +22,8 @@ #include <linux/sysfs.h> #include "iio_dummy_evgen.h" -#include "iio.h" -#include "sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> /* Fiddly bit of faking and irq without hardware */ #define IIO_EVENTGEN_NO 10 diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c index a603a5f..b03554f 100644 --- a/drivers/staging/iio/iio_hwmon.c +++ b/drivers/staging/iio/iio_hwmon.c @@ -14,8 +14,8 @@ #include <linux/platform_device.h> #include <linux/hwmon.h> #include <linux/hwmon-sysfs.h> -#include "consumer.h" -#include "types.h" +#include <linux/iio/consumer.h> +#include <linux/iio/types.h> /** * struct iio_hwmon_state - device instance state diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index e3a9457..3104119 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -19,10 +19,10 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include "iio.h" -#include "sysfs.h" -#include "events.h" -#include "buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> +#include <linux/iio/buffer.h> #include "iio_simple_dummy.h" /* @@ -73,6 +73,12 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* What other information is available? */ .info_mask = /* + * in_voltage0_raw + * Raw (unscaled no bias removal etc) measurement + * from the device. + */ + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + /* * in_voltage0_offset * Offset for userspace to apply prior to scale * when converting to standard units (microvolts) @@ -114,6 +120,12 @@ static struct iio_chan_spec iio_dummy_channels[] = { .channel2 = 2, .info_mask = /* + * in_voltage1-voltage2_raw + * Raw (unscaled no bias removal etc) measurement + * from the device. + */ + IIO_CHAN_INFO_RAW_SEPARATE_BIT | + /* * in_voltage-voltage_scale * Shared version of scale - shared by differential * input channels of type IIO_VOLTAGE. @@ -135,6 +147,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { .channel = 3, .channel2 = 4, .info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, .scan_index = diffvoltage3m4, .scan_type = { @@ -154,6 +167,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* Channel 2 is use for modifiers */ .channel2 = IIO_MOD_X, .info_mask = + IIO_CHAN_INFO_RAW_SEPARATE_BIT | /* * Internal bias correction value. Applied * by the hardware or driver prior to userspace @@ -177,6 +191,7 @@ static struct iio_chan_spec iio_dummy_channels[] = { /* DAC channel out_voltage0_raw */ { .type = IIO_VOLTAGE, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .output = 1, .indexed = 1, .channel = 0, @@ -203,7 +218,7 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev, mutex_lock(&st->lock); switch (mask) { - case 0: /* magic value - channel value read */ + case IIO_CHAN_INFO_RAW: /* magic value - channel value read */ switch (chan->type) { case IIO_VOLTAGE: if (chan->output) { @@ -290,7 +305,7 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev, struct iio_dummy_state *st = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: if (chan->output == 0) return -EINVAL; @@ -377,7 +392,7 @@ static int __devinit iio_dummy_probe(int index) * It also has a region (accessed by iio_priv() * for chip specific state information. */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -455,9 +470,7 @@ error_unconfigure_buffer: error_unregister_events: iio_simple_dummy_events_unregister(indio_dev); error_free_device: - /* Note free device should only be called, before registration - * has succeeded. */ - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -494,7 +507,7 @@ static int iio_dummy_remove(int index) goto error_ret; /* Free all structures */ - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index bb4daf7..fdfc8739 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -18,9 +18,9 @@ #include <linux/irq.h> #include <linux/bitmap.h> -#include "iio.h" -#include "trigger_consumer.h" -#include "kfifo_buf.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger_consumer.h> +#include <linux/iio/kfifo_buf.h> #include "iio_simple_dummy.h" @@ -37,7 +37,7 @@ static const s16 fakedata[] = { * @irq: the interrupt number * @p: private data - always a pointer to the poll func. * - * This is the guts of buffered capture. On a trigger event occuring, + * This is the guts of buffered capture. On a trigger event occurring, * if the pollfunc is attached then this handler is called as a threaded * interrupt (and hence may sleep). It is responsible for grabbing data * from the device and pushing it into the associated buffer. @@ -48,12 +48,9 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct iio_buffer *buffer = indio_dev->buffer; int len = 0; - /* - * The datasize is obtained from the buffer. It was stored when - * the preenable setup function was called. - */ - size_t datasize = buffer->access->get_bytes_per_datum(buffer); - u16 *data = kmalloc(datasize, GFP_KERNEL); + u16 *data; + + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -64,7 +61,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) * up a fast read. The capture will consist of all of them. * Hence we just call the grab data function and fill the * buffer without processing. - * sofware scans: can be considered to be random access + * software scans: can be considered to be random access * so efficient reading is just a case of minimal bus * transactions. * software culled hardware scans: @@ -87,7 +84,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) } } /* Store a timestampe at an 8 byte boundary */ - if (buffer->scan_timestamp) + if (indio_dev->scan_timestamp) *(s64 *)(((phys_addr_t)data + len + sizeof(s64) - 1) & ~(sizeof(s64) - 1)) = iio_get_time_ns(); diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c index 449c7a5..317b774 100644 --- a/drivers/staging/iio/iio_simple_dummy_events.c +++ b/drivers/staging/iio/iio_simple_dummy_events.c @@ -12,9 +12,9 @@ #include <linux/interrupt.h> #include <linux/irq.h> -#include "iio.h" -#include "sysfs.h" -#include "events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include "iio_simple_dummy.h" /* Evgen 'fakes' interrupt events for this example */ @@ -122,7 +122,7 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev, * @private: pointer to device instance state. * * This handler is responsible for querying the device to find out what - * event occured and for then pushing that event towards userspace. + * event occurred and for then pushing that event towards userspace. * Here only one event occurs so we push that directly on with locally * grabbed timestamp. */ diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index cd82b56..a8e51bc 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -19,9 +19,9 @@ #include <linux/module.h> #include <asm/div64.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "../ring_sw.h" #include "ad5933.h" @@ -109,15 +109,46 @@ static struct ad5933_platform_data ad5933_default_pdata = { }; static struct iio_chan_spec ad5933_channels[] = { - IIO_CHAN(IIO_TEMP, 0, 1, 1, NULL, 0, 0, 0, - 0, AD5933_REG_TEMP_DATA, IIO_ST('s', 14, 16, 0), 0), - /* Ring Channels */ - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "real_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - AD5933_REG_REAL_DATA, 0, IIO_ST('s', 16, 16, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "imag_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - AD5933_REG_IMAG_DATA, 1, IIO_ST('s', 16, 16, 0), 0), + { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + .address = AD5933_REG_TEMP_DATA, + .scan_type = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + }, + }, { /* Ring Channels */ + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "real_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = AD5933_REG_REAL_DATA, + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "imag_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = AD5933_REG_IMAG_DATA, + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + }, + }, }; static int ad5933_i2c_write(struct i2c_client *client, @@ -260,7 +291,7 @@ static ssize_t ad5933_show_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5933_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -289,7 +320,7 @@ static ssize_t ad5933_store_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5933_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; @@ -323,7 +354,7 @@ static ssize_t ad5933_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5933_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret = 0, len = 0; @@ -366,7 +397,7 @@ static ssize_t ad5933_store(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad5933_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; @@ -495,7 +526,8 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: if (iio_buffer_enabled(indio_dev)) { ret = -EBUSY; goto out; @@ -537,19 +569,14 @@ static const struct iio_info ad5933_info = { static int ad5933_ring_preenable(struct iio_dev *indio_dev) { struct ad5933_state *st = iio_priv(indio_dev); - size_t d_size; int ret; if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; - d_size = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - ad5933_channels[1].scan_type.storagebits / 8; - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; ret = ad5933_reset(st); if (ret < 0) @@ -678,7 +705,7 @@ static int __devinit ad5933_probe(struct i2c_client *client, int ret, voltage_uv = 0; struct ad5933_platform_data *pdata = client->dev.platform_data; struct ad5933_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; @@ -757,7 +784,7 @@ error_put_reg: if (!IS_ERR(st->reg)) regulator_put(st->reg); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -774,7 +801,7 @@ static __devexit int ad5933_remove(struct i2c_client *client) regulator_disable(st->reg); regulator_put(st->reg); } - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index e73ad78..1f6bd85 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -26,9 +26,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "adis16400.h" enum adis16400_chip_variant { @@ -179,7 +179,7 @@ static ssize_t adis16400_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret, len = 0; ret = adis16400_get_freq(indio_dev); if (ret < 0) @@ -225,7 +225,7 @@ static ssize_t adis16400_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16400_state *st = iio_priv(indio_dev); long val; int ret; @@ -279,7 +279,7 @@ static ssize_t adis16400_write_reset(struct device *dev, if (ret < 0) return ret; if (val) { - ret = adis16400_reset(dev_get_drvdata(dev)); + ret = adis16400_reset(dev_to_iio_dev(dev)); if (ret < 0) return ret; } @@ -545,7 +545,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, s16 val16; switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: mutex_lock(&indio_dev->mlock); ret = adis16400_spi_read_reg_16(indio_dev, adis16400_addresses[chan->address][0], @@ -635,7 +635,8 @@ static struct iio_chan_spec adis16400_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 14, 16, 0) @@ -643,7 +644,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -653,7 +655,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -663,7 +666,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, @@ -673,7 +677,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -683,7 +688,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -693,7 +699,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -703,7 +710,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_x, .scan_index = ADIS16400_SCAN_MAGN_X, @@ -712,7 +720,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_y, .scan_index = ADIS16400_SCAN_MAGN_Y, @@ -721,7 +730,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_MAGN, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = magn_z, .scan_index = ADIS16400_SCAN_MAGN_Z, @@ -730,7 +740,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, .scan_index = ADIS16400_SCAN_TEMP, @@ -739,7 +750,8 @@ static struct iio_chan_spec adis16400_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16400_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -753,7 +765,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 12, 16, 0) @@ -761,7 +774,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -771,7 +785,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -781,17 +796,19 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, .scan_index = ADIS16400_SCAN_GYRO_Z, .scan_type = IIO_ST('s', 14, 16, 0), }, { - .type = IIO_ACCEL, + .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -801,7 +818,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -811,7 +829,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -822,7 +841,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 0, .extend_name = "x", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = temp0, @@ -833,7 +853,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 1, .extend_name = "y", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = temp1, @@ -844,7 +865,8 @@ static struct iio_chan_spec adis16350_channels[] = { .indexed = 1, .channel = 2, .extend_name = "z", - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp2, .scan_index = ADIS16350_SCAN_TEMP_Z, @@ -853,7 +875,8 @@ static struct iio_chan_spec adis16350_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16350_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -867,7 +890,8 @@ static struct iio_chan_spec adis16300_channels[] = { .indexed = 1, .channel = 0, .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, .scan_type = IIO_ST('u', 12, 16, 0) @@ -875,7 +899,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -885,7 +910,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -895,7 +921,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -905,7 +932,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -915,7 +943,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = temp, .scan_index = ADIS16400_SCAN_TEMP, @@ -924,7 +953,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_VOLTAGE, .indexed = 1, .channel = 1, - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in1, .scan_index = ADIS16350_SCAN_ADC_0, .scan_type = IIO_ST('s', 12, 16, 0), @@ -932,7 +962,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_x, .scan_index = ADIS16300_SCAN_INCLI_X, .scan_type = IIO_ST('s', 13, 16, 0), @@ -940,7 +971,8 @@ static struct iio_chan_spec adis16300_channels[] = { .type = IIO_INCLI, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = incli_y, .scan_index = ADIS16300_SCAN_INCLI_Y, .scan_type = IIO_ST('s', 13, 16, 0), @@ -953,7 +985,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, @@ -963,7 +996,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_y, @@ -973,7 +1007,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ANGL_VEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_z, @@ -983,7 +1018,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_x, @@ -993,7 +1029,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_y, @@ -1003,7 +1040,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_ACCEL, .modified = 1, .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = accel_z, @@ -1013,7 +1051,8 @@ static const struct iio_chan_spec adis16334_channels[] = { .type = IIO_TEMP, .indexed = 1, .channel = 0, - .info_mask = IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | IIO_CHAN_INFO_SCALE_SHARED_BIT, .address = accel_z, .scan_index = ADIS16400_SCAN_ACC_Z, @@ -1122,7 +1161,7 @@ static int __devinit adis16400_probe(struct spi_device *spi) { int ret; struct adis16400_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -1172,14 +1211,14 @@ static int __devinit adis16400_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq) adis16400_remove_trigger(indio_dev); error_uninitialize_ring: iio_buffer_unregister(indio_dev); error_unreg_ring_funcs: adis16400_unconfigure_ring(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -1198,7 +1237,7 @@ static int adis16400_remove(struct spi_device *spi) adis16400_remove_trigger(indio_dev); iio_buffer_unregister(indio_dev); adis16400_unconfigure_ring(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index 8daa038..809e2c4 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -6,20 +6,19 @@ #include <linux/bitops.h> #include <linux/export.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "adis16400.h" /** * adis16400_spi_read_burst() - read all data registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device * @rx: somewhere to pass back the value read (min size is 24 bytes) **/ -static int adis16400_spi_read_burst(struct device *dev, u8 *rx) +static int adis16400_spi_read_burst(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16400_state *st = iio_priv(indio_dev); u32 old_speed_hz = st->us->max_speed_hz; int ret; @@ -71,9 +70,8 @@ static const u16 read_all_tx_array[] = { cpu_to_be16(ADIS16400_READ_REG(ADIS16400_AUX_ADC)), }; -static int adis16350_spi_read_all(struct device *dev, u8 *rx) +static int adis16350_spi_read_all(struct iio_dev *indio_dev, u8 *rx) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16400_state *st = iio_priv(indio_dev); struct spi_message msg; @@ -119,12 +117,12 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) struct iio_buffer *ring = indio_dev->buffer; int i = 0, j, ret = 0; s16 *data; - size_t datasize = ring->access->get_bytes_per_datum(ring); + /* Asumption that long is enough for maximum channels */ unsigned long mask = *indio_dev->active_scan_mask; int scan_count = bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); - data = kmalloc(datasize , GFP_KERNEL); + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return -ENOMEM; @@ -132,13 +130,13 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) if (scan_count) { if (st->variant->flags & ADIS16400_NO_BURST) { - ret = adis16350_spi_read_all(&indio_dev->dev, st->rx); + ret = adis16350_spi_read_all(indio_dev, st->rx); if (ret < 0) goto err; for (; i < scan_count; i++) data[i] = *(s16 *)(st->rx + i*2); } else { - ret = adis16400_spi_read_burst(&indio_dev->dev, st->rx); + ret = adis16400_spi_read_burst(indio_dev, st->rx); if (ret < 0) goto err; for (; i < scan_count; i++) { diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c index 5bf0007..42a678e 100644 --- a/drivers/staging/iio/imu/adis16400_trigger.c +++ b/drivers/staging/iio/imu/adis16400_trigger.c @@ -3,8 +3,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "adis16400.h" /** @@ -29,7 +29,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev) int ret; struct adis16400_state *st = iio_priv(indio_dev); - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id); if (st->trig == NULL) { @@ -59,7 +59,7 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -70,5 +70,5 @@ void adis16400_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/industrialio-buffer.c b/drivers/staging/iio/industrialio-buffer.c deleted file mode 100644 index 386ba76..0000000 --- a/drivers/staging/iio/industrialio-buffer.c +++ /dev/null @@ -1,734 +0,0 @@ -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Handling of buffer allocation / resizing. - * - * - * Things to look at here. - * - Better memory allocation techniques? - * - Alternative access techniques? - */ -#include <linux/kernel.h> -#include <linux/export.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/slab.h> -#include <linux/poll.h> - -#include "iio.h" -#include "iio_core.h" -#include "sysfs.h" -#include "buffer.h" - -static const char * const iio_endian_prefix[] = { - [IIO_BE] = "be", - [IIO_LE] = "le", -}; - -/** - * iio_buffer_read_first_n_outer() - chrdev read for buffer access - * - * This function relies on all buffer implementations having an - * iio_buffer as their first element. - **/ -ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, - size_t n, loff_t *f_ps) -{ - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; - - if (!rb || !rb->access->read_first_n) - return -EINVAL; - return rb->access->read_first_n(rb, n, buf); -} - -/** - * iio_buffer_poll() - poll the buffer to find out if it has data - */ -unsigned int iio_buffer_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct iio_dev *indio_dev = filp->private_data; - struct iio_buffer *rb = indio_dev->buffer; - - poll_wait(filp, &rb->pollq, wait); - if (rb->stufftoread) - return POLLIN | POLLRDNORM; - /* need a way of knowing if there may be enough data... */ - return 0; -} - -void iio_buffer_init(struct iio_buffer *buffer) -{ - INIT_LIST_HEAD(&buffer->demux_list); - init_waitqueue_head(&buffer->pollq); -} -EXPORT_SYMBOL(iio_buffer_init); - -static ssize_t iio_show_scan_index(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index); -} - -static ssize_t iio_show_fixed_type(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - u8 type = this_attr->c->scan_type.endianness; - - if (type == IIO_CPU) { -#ifdef __LITTLE_ENDIAN - type = IIO_LE; -#else - type = IIO_BE; -#endif - } - return sprintf(buf, "%s:%c%d/%d>>%u\n", - iio_endian_prefix[type], - this_attr->c->scan_type.sign, - this_attr->c->scan_type.realbits, - this_attr->c->scan_type.storagebits, - this_attr->c->scan_type.shift); -} - -static ssize_t iio_scan_el_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - ret = test_bit(to_iio_dev_attr(attr)->address, - indio_dev->buffer->scan_mask); - - return sprintf(buf, "%d\n", ret); -} - -static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit) -{ - clear_bit(bit, buffer->scan_mask); - return 0; -} - -static ssize_t iio_scan_el_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret = 0; - bool state; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - state = !(buf[0] == '0'); - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - ret = iio_scan_mask_query(indio_dev, buffer, this_attr->address); - if (ret < 0) - goto error_ret; - if (!state && ret) { - ret = iio_scan_mask_clear(buffer, this_attr->address); - if (ret) - goto error_ret; - } else if (state && !ret) { - ret = iio_scan_mask_set(indio_dev, buffer, this_attr->address); - if (ret) - goto error_ret; - } - -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret < 0 ? ret : len; - -} - -static ssize_t iio_scan_el_ts_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", indio_dev->buffer->scan_timestamp); -} - -static ssize_t iio_scan_el_ts_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret = 0; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - bool state; - - state = !(buf[0] == '0'); - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - indio_dev->buffer->scan_timestamp = state; -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} - -static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan) -{ - int ret, attrcount = 0; - struct iio_buffer *buffer = indio_dev->buffer; - - ret = __iio_add_chan_devattr("index", - chan, - &iio_show_scan_index, - NULL, - 0, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - if (ret) - goto error_ret; - attrcount++; - ret = __iio_add_chan_devattr("type", - chan, - &iio_show_fixed_type, - NULL, - 0, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - if (ret) - goto error_ret; - attrcount++; - if (chan->type != IIO_TIMESTAMP) - ret = __iio_add_chan_devattr("en", - chan, - &iio_scan_el_show, - &iio_scan_el_store, - chan->scan_index, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - else - ret = __iio_add_chan_devattr("en", - chan, - &iio_scan_el_ts_show, - &iio_scan_el_ts_store, - chan->scan_index, - 0, - &indio_dev->dev, - &buffer->scan_el_dev_attr_list); - attrcount++; - ret = attrcount; -error_ret: - return ret; -} - -static void iio_buffer_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev, - struct iio_dev_attr *p) -{ - kfree(p->dev_attr.attr.name); - kfree(p); -} - -static void __iio_buffer_attr_cleanup(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p, *n; - struct iio_buffer *buffer = indio_dev->buffer; - - list_for_each_entry_safe(p, n, - &buffer->scan_el_dev_attr_list, l) - iio_buffer_remove_and_free_scan_dev_attr(indio_dev, p); -} - -static const char * const iio_scan_elements_group_name = "scan_elements"; - -int iio_buffer_register(struct iio_dev *indio_dev, - const struct iio_chan_spec *channels, - int num_channels) -{ - struct iio_dev_attr *p; - struct attribute **attr; - struct iio_buffer *buffer = indio_dev->buffer; - int ret, i, attrn, attrcount, attrcount_orig = 0; - - if (buffer->attrs) - indio_dev->groups[indio_dev->groupcounter++] = buffer->attrs; - - if (buffer->scan_el_attrs != NULL) { - attr = buffer->scan_el_attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list); - if (channels) { - /* new magic */ - for (i = 0; i < num_channels; i++) { - /* Establish necessary mask length */ - if (channels[i].scan_index > - (int)indio_dev->masklength - 1) - indio_dev->masklength - = indio_dev->channels[i].scan_index + 1; - - ret = iio_buffer_add_channel_sysfs(indio_dev, - &channels[i]); - if (ret < 0) - goto error_cleanup_dynamic; - attrcount += ret; - if (channels[i].type == IIO_TIMESTAMP) - buffer->scan_index_timestamp = - channels[i].scan_index; - } - if (indio_dev->masklength && buffer->scan_mask == NULL) { - buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength), - sizeof(*buffer->scan_mask), - GFP_KERNEL); - if (buffer->scan_mask == NULL) { - ret = -ENOMEM; - goto error_cleanup_dynamic; - } - } - } - - buffer->scan_el_group.name = iio_scan_elements_group_name; - - buffer->scan_el_group.attrs = kcalloc(attrcount + 1, - sizeof(buffer->scan_el_group.attrs[0]), - GFP_KERNEL); - if (buffer->scan_el_group.attrs == NULL) { - ret = -ENOMEM; - goto error_free_scan_mask; - } - if (buffer->scan_el_attrs) - memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs, - sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig); - attrn = attrcount_orig; - - list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l) - buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group; - - return 0; - -error_free_scan_mask: - kfree(buffer->scan_mask); -error_cleanup_dynamic: - __iio_buffer_attr_cleanup(indio_dev); - - return ret; -} -EXPORT_SYMBOL(iio_buffer_register); - -void iio_buffer_unregister(struct iio_dev *indio_dev) -{ - kfree(indio_dev->buffer->scan_mask); - kfree(indio_dev->buffer->scan_el_group.attrs); - __iio_buffer_attr_cleanup(indio_dev); -} -EXPORT_SYMBOL(iio_buffer_unregister); - -ssize_t iio_buffer_read_length(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - if (buffer->access->get_length) - return sprintf(buf, "%d\n", - buffer->access->get_length(buffer)); - - return 0; -} -EXPORT_SYMBOL(iio_buffer_read_length); - -ssize_t iio_buffer_write_length(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - ulong val; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return ret; - - if (buffer->access->get_length) - if (val == buffer->access->get_length(buffer)) - return len; - - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - } else { - if (buffer->access->set_length) - buffer->access->set_length(buffer, val); - ret = 0; - } - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; -} -EXPORT_SYMBOL(iio_buffer_write_length); - -ssize_t iio_buffer_store_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - bool requested_state, current_state; - int previous_mode; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - mutex_lock(&indio_dev->mlock); - previous_mode = indio_dev->currentmode; - requested_state = !(buf[0] == '0'); - current_state = iio_buffer_enabled(indio_dev); - if (current_state == requested_state) { - printk(KERN_INFO "iio-buffer, current state requested again\n"); - goto done; - } - if (requested_state) { - if (indio_dev->setup_ops->preenable) { - ret = indio_dev->setup_ops->preenable(indio_dev); - if (ret) { - printk(KERN_ERR - "Buffer not started:" - "buffer preenable failed\n"); - goto error_ret; - } - } - if (buffer->access->request_update) { - ret = buffer->access->request_update(buffer); - if (ret) { - printk(KERN_INFO - "Buffer not started:" - "buffer parameter update failed\n"); - goto error_ret; - } - } - /* Definitely possible for devices to support both of these.*/ - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { - if (!indio_dev->trig) { - printk(KERN_INFO - "Buffer not started: no trigger\n"); - ret = -EINVAL; - goto error_ret; - } - indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; - } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) - indio_dev->currentmode = INDIO_BUFFER_HARDWARE; - else { /* should never be reached */ - ret = -EINVAL; - goto error_ret; - } - - if (indio_dev->setup_ops->postenable) { - ret = indio_dev->setup_ops->postenable(indio_dev); - if (ret) { - printk(KERN_INFO - "Buffer not started:" - "postenable failed\n"); - indio_dev->currentmode = previous_mode; - if (indio_dev->setup_ops->postdisable) - indio_dev->setup_ops-> - postdisable(indio_dev); - goto error_ret; - } - } - } else { - if (indio_dev->setup_ops->predisable) { - ret = indio_dev->setup_ops->predisable(indio_dev); - if (ret) - goto error_ret; - } - indio_dev->currentmode = INDIO_DIRECT_MODE; - if (indio_dev->setup_ops->postdisable) { - ret = indio_dev->setup_ops->postdisable(indio_dev); - if (ret) - goto error_ret; - } - } -done: - mutex_unlock(&indio_dev->mlock); - return len; - -error_ret: - mutex_unlock(&indio_dev->mlock); - return ret; -} -EXPORT_SYMBOL(iio_buffer_store_enable); - -ssize_t iio_buffer_show_enable(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev)); -} -EXPORT_SYMBOL(iio_buffer_show_enable); - -/* note NULL used as error indicator as it doesn't make sense. */ -static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks, - unsigned int masklength, - const unsigned long *mask) -{ - if (bitmap_empty(mask, masklength)) - return NULL; - while (*av_masks) { - if (bitmap_subset(mask, av_masks, masklength)) - return av_masks; - av_masks += BITS_TO_LONGS(masklength); - } - return NULL; -} - -int iio_sw_buffer_preenable(struct iio_dev *indio_dev) -{ - struct iio_buffer *buffer = indio_dev->buffer; - const struct iio_chan_spec *ch; - unsigned bytes = 0; - int length, i; - dev_dbg(&indio_dev->dev, "%s\n", __func__); - - /* How much space will the demuxed element take? */ - for_each_set_bit(i, buffer->scan_mask, - indio_dev->masklength) { - ch = iio_find_channel_from_si(indio_dev, i); - length = ch->scan_type.storagebits/8; - bytes = ALIGN(bytes, length); - bytes += length; - } - if (buffer->scan_timestamp) { - ch = iio_find_channel_from_si(indio_dev, - buffer->scan_index_timestamp); - length = ch->scan_type.storagebits/8; - bytes = ALIGN(bytes, length); - bytes += length; - } - buffer->access->set_bytes_per_datum(buffer, bytes); - - /* What scan mask do we actually have ?*/ - if (indio_dev->available_scan_masks) - indio_dev->active_scan_mask = - iio_scan_mask_match(indio_dev->available_scan_masks, - indio_dev->masklength, - buffer->scan_mask); - else - indio_dev->active_scan_mask = buffer->scan_mask; - iio_update_demux(indio_dev); - - if (indio_dev->info->update_scan_mode) - return indio_dev->info - ->update_scan_mode(indio_dev, - indio_dev->active_scan_mask); - return 0; -} -EXPORT_SYMBOL(iio_sw_buffer_preenable); - -/** - * iio_scan_mask_set() - set particular bit in the scan mask - * @buffer: the buffer whose scan mask we are interested in - * @bit: the bit to be set. - **/ -int iio_scan_mask_set(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) -{ - const unsigned long *mask; - unsigned long *trialmask; - - trialmask = kmalloc(sizeof(*trialmask)* - BITS_TO_LONGS(indio_dev->masklength), - GFP_KERNEL); - - if (trialmask == NULL) - return -ENOMEM; - if (!indio_dev->masklength) { - WARN_ON("trying to set scanmask prior to registering buffer\n"); - kfree(trialmask); - return -EINVAL; - } - bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength); - set_bit(bit, trialmask); - - if (indio_dev->available_scan_masks) { - mask = iio_scan_mask_match(indio_dev->available_scan_masks, - indio_dev->masklength, - trialmask); - if (!mask) { - kfree(trialmask); - return -EINVAL; - } - } - bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength); - - kfree(trialmask); - - return 0; -}; -EXPORT_SYMBOL_GPL(iio_scan_mask_set); - -int iio_scan_mask_query(struct iio_dev *indio_dev, - struct iio_buffer *buffer, int bit) -{ - if (bit > indio_dev->masklength) - return -EINVAL; - - if (!buffer->scan_mask) - return 0; - - return test_bit(bit, buffer->scan_mask); -}; -EXPORT_SYMBOL_GPL(iio_scan_mask_query); - -/** - * struct iio_demux_table() - table describing demux memcpy ops - * @from: index to copy from - * @to: index to copy to - * @length: how many bytes to copy - * @l: list head used for management - */ -struct iio_demux_table { - unsigned from; - unsigned to; - unsigned length; - struct list_head l; -}; - -static unsigned char *iio_demux(struct iio_buffer *buffer, - unsigned char *datain) -{ - struct iio_demux_table *t; - - if (list_empty(&buffer->demux_list)) - return datain; - list_for_each_entry(t, &buffer->demux_list, l) - memcpy(buffer->demux_bounce + t->to, - datain + t->from, t->length); - - return buffer->demux_bounce; -} - -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp) -{ - unsigned char *dataout = iio_demux(buffer, data); - - return buffer->access->store_to(buffer, dataout, timestamp); -} -EXPORT_SYMBOL_GPL(iio_push_to_buffer); - -int iio_update_demux(struct iio_dev *indio_dev) -{ - const struct iio_chan_spec *ch; - struct iio_buffer *buffer = indio_dev->buffer; - int ret, in_ind = -1, out_ind, length; - unsigned in_loc = 0, out_loc = 0; - struct iio_demux_table *p, *q; - - /* Clear out any old demux */ - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } - kfree(buffer->demux_bounce); - buffer->demux_bounce = NULL; - - /* First work out which scan mode we will actually have */ - if (bitmap_equal(indio_dev->active_scan_mask, - buffer->scan_mask, - indio_dev->masklength)) - return 0; - - /* Now we have the two masks, work from least sig and build up sizes */ - for_each_set_bit(out_ind, - indio_dev->active_scan_mask, - indio_dev->masklength) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - while (in_ind != out_ind) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); - ch = iio_find_channel_from_si(indio_dev, in_ind); - length = ch->scan_type.storagebits/8; - /* Make sure we are aligned */ - in_loc += length; - if (in_loc % length) - in_loc += length - in_loc % length; - } - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - ch = iio_find_channel_from_si(indio_dev, in_ind); - length = ch->scan_type.storagebits/8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); - out_loc += length; - in_loc += length; - } - /* Relies on scan_timestamp being last */ - if (buffer->scan_timestamp) { - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - ch = iio_find_channel_from_si(indio_dev, - buffer->scan_index_timestamp); - length = ch->scan_type.storagebits/8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); - out_loc += length; - in_loc += length; - } - buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL); - if (buffer->demux_bounce == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } - return 0; - -error_clear_mux_table: - list_for_each_entry_safe(p, q, &buffer->demux_list, l) { - list_del(&p->l); - kfree(p); - } - return ret; -} -EXPORT_SYMBOL_GPL(iio_update_demux); diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c deleted file mode 100644 index d303bfb..0000000 --- a/drivers/staging/iio/industrialio-core.c +++ /dev/null @@ -1,927 +0,0 @@ -/* The industrial I/O core - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Based on elements of hwmon and input subsystems. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/idr.h> -#include <linux/kdev_t.h> -#include <linux/err.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/poll.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/cdev.h> -#include <linux/slab.h> -#include <linux/anon_inodes.h> -#include <linux/debugfs.h> -#include "iio.h" -#include "iio_core.h" -#include "iio_core_trigger.h" -#include "sysfs.h" -#include "events.h" - -/* IDA to assign each registered device a unique id*/ -static DEFINE_IDA(iio_ida); - -static dev_t iio_devt; - -#define IIO_DEV_MAX 256 -struct bus_type iio_bus_type = { - .name = "iio", -}; -EXPORT_SYMBOL(iio_bus_type); - -static struct dentry *iio_debugfs_dentry; - -static const char * const iio_data_type_name[] = { - [IIO_RAW] = "raw", - [IIO_PROCESSED] = "input", -}; - -static const char * const iio_direction[] = { - [0] = "in", - [1] = "out", -}; - -static const char * const iio_chan_type_name_spec[] = { - [IIO_VOLTAGE] = "voltage", - [IIO_CURRENT] = "current", - [IIO_POWER] = "power", - [IIO_ACCEL] = "accel", - [IIO_ANGL_VEL] = "anglvel", - [IIO_MAGN] = "magn", - [IIO_LIGHT] = "illuminance", - [IIO_INTENSITY] = "intensity", - [IIO_PROXIMITY] = "proximity", - [IIO_TEMP] = "temp", - [IIO_INCLI] = "incli", - [IIO_ROT] = "rot", - [IIO_ANGL] = "angl", - [IIO_TIMESTAMP] = "timestamp", - [IIO_CAPACITANCE] = "capacitance", -}; - -static const char * const iio_modifier_names[] = { - [IIO_MOD_X] = "x", - [IIO_MOD_Y] = "y", - [IIO_MOD_Z] = "z", - [IIO_MOD_LIGHT_BOTH] = "both", - [IIO_MOD_LIGHT_IR] = "ir", -}; - -/* relies on pairs of these shared then separate */ -static const char * const iio_chan_info_postfix[] = { - [IIO_CHAN_INFO_SCALE] = "scale", - [IIO_CHAN_INFO_OFFSET] = "offset", - [IIO_CHAN_INFO_CALIBSCALE] = "calibscale", - [IIO_CHAN_INFO_CALIBBIAS] = "calibbias", - [IIO_CHAN_INFO_PEAK] = "peak_raw", - [IIO_CHAN_INFO_PEAK_SCALE] = "peak_scale", - [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW] = "quadrature_correction_raw", - [IIO_CHAN_INFO_AVERAGE_RAW] = "mean_raw", - [IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY] - = "filter_low_pass_3db_frequency", -}; - -const struct iio_chan_spec -*iio_find_channel_from_si(struct iio_dev *indio_dev, int si) -{ - int i; - - for (i = 0; i < indio_dev->num_channels; i++) - if (indio_dev->channels[i].scan_index == si) - return &indio_dev->channels[i]; - return NULL; -} - -/* This turns up an awful lot */ -ssize_t iio_read_const_attr(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string); -} -EXPORT_SYMBOL(iio_read_const_attr); - -static int __init iio_init(void) -{ - int ret; - - /* Register sysfs bus */ - ret = bus_register(&iio_bus_type); - if (ret < 0) { - printk(KERN_ERR - "%s could not register bus type\n", - __FILE__); - goto error_nothing; - } - - ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); - if (ret < 0) { - printk(KERN_ERR "%s: failed to allocate char dev region\n", - __FILE__); - goto error_unregister_bus_type; - } - - iio_debugfs_dentry = debugfs_create_dir("iio", NULL); - - return 0; - -error_unregister_bus_type: - bus_unregister(&iio_bus_type); -error_nothing: - return ret; -} - -static void __exit iio_exit(void) -{ - if (iio_devt) - unregister_chrdev_region(iio_devt, IIO_DEV_MAX); - bus_unregister(&iio_bus_type); - debugfs_remove(iio_debugfs_dentry); -} - -#if defined(CONFIG_DEBUG_FS) -static int iio_debugfs_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - - return 0; -} - -static ssize_t iio_debugfs_read_reg(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct iio_dev *indio_dev = file->private_data; - char buf[20]; - unsigned val = 0; - ssize_t len; - int ret; - - ret = indio_dev->info->debugfs_reg_access(indio_dev, - indio_dev->cached_reg_addr, - 0, &val); - if (ret) - dev_err(indio_dev->dev.parent, "%s: read failed\n", __func__); - - len = snprintf(buf, sizeof(buf), "0x%X\n", val); - - return simple_read_from_buffer(userbuf, count, ppos, buf, len); -} - -static ssize_t iio_debugfs_write_reg(struct file *file, - const char __user *userbuf, size_t count, loff_t *ppos) -{ - struct iio_dev *indio_dev = file->private_data; - unsigned reg, val; - char buf[80]; - int ret; - - count = min_t(size_t, count, (sizeof(buf)-1)); - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - - buf[count] = 0; - - ret = sscanf(buf, "%i %i", ®, &val); - - switch (ret) { - case 1: - indio_dev->cached_reg_addr = reg; - break; - case 2: - indio_dev->cached_reg_addr = reg; - ret = indio_dev->info->debugfs_reg_access(indio_dev, reg, - val, NULL); - if (ret) { - dev_err(indio_dev->dev.parent, "%s: write failed\n", - __func__); - return ret; - } - break; - default: - return -EINVAL; - } - - return count; -} - -static const struct file_operations iio_debugfs_reg_fops = { - .open = iio_debugfs_open, - .read = iio_debugfs_read_reg, - .write = iio_debugfs_write_reg, -}; - -static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) -{ - debugfs_remove_recursive(indio_dev->debugfs_dentry); -} - -static int iio_device_register_debugfs(struct iio_dev *indio_dev) -{ - struct dentry *d; - - if (indio_dev->info->debugfs_reg_access == NULL) - return 0; - - if (IS_ERR(iio_debugfs_dentry)) - return 0; - - indio_dev->debugfs_dentry = - debugfs_create_dir(dev_name(&indio_dev->dev), - iio_debugfs_dentry); - if (IS_ERR(indio_dev->debugfs_dentry)) - return PTR_ERR(indio_dev->debugfs_dentry); - - if (indio_dev->debugfs_dentry == NULL) { - dev_warn(indio_dev->dev.parent, - "Failed to create debugfs directory\n"); - return -EFAULT; - } - - d = debugfs_create_file("direct_reg_access", 0644, - indio_dev->debugfs_dentry, - indio_dev, &iio_debugfs_reg_fops); - if (!d) { - iio_device_unregister_debugfs(indio_dev); - return -ENOMEM; - } - - return 0; -} -#else -static int iio_device_register_debugfs(struct iio_dev *indio_dev) -{ - return 0; -} - -static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) -{ -} -#endif /* CONFIG_DEBUG_FS */ - -static ssize_t iio_read_channel_ext_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - const struct iio_chan_spec_ext_info *ext_info; - - ext_info = &this_attr->c->ext_info[this_attr->address]; - - return ext_info->read(indio_dev, this_attr->c, buf); -} - -static ssize_t iio_write_channel_ext_info(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - const struct iio_chan_spec_ext_info *ext_info; - - ext_info = &this_attr->c->ext_info[this_attr->address]; - - return ext_info->write(indio_dev, this_attr->c, buf, len); -} - -static ssize_t iio_read_channel_info(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val, val2; - int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, - &val, &val2, this_attr->address); - - if (ret < 0) - return ret; - - if (ret == IIO_VAL_INT) - return sprintf(buf, "%d\n", val); - else if (ret == IIO_VAL_INT_PLUS_MICRO) { - if (val2 < 0) - return sprintf(buf, "-%d.%06u\n", val, -val2); - else - return sprintf(buf, "%d.%06u\n", val, val2); - } else if (ret == IIO_VAL_INT_PLUS_NANO) { - if (val2 < 0) - return sprintf(buf, "-%d.%09u\n", val, -val2); - else - return sprintf(buf, "%d.%09u\n", val, val2); - } else - return 0; -} - -static ssize_t iio_write_channel_info(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret, integer = 0, fract = 0, fract_mult = 100000; - bool integer_part = true, negative = false; - - /* Assumes decimal - precision based on number of digits */ - if (!indio_dev->info->write_raw) - return -EINVAL; - - if (indio_dev->info->write_raw_get_fmt) - switch (indio_dev->info->write_raw_get_fmt(indio_dev, - this_attr->c, this_attr->address)) { - case IIO_VAL_INT_PLUS_MICRO: - fract_mult = 100000; - break; - case IIO_VAL_INT_PLUS_NANO: - fract_mult = 100000000; - break; - default: - return -EINVAL; - } - - if (buf[0] == '-') { - negative = true; - buf++; - } - - while (*buf) { - if ('0' <= *buf && *buf <= '9') { - if (integer_part) - integer = integer*10 + *buf - '0'; - else { - fract += fract_mult*(*buf - '0'); - if (fract_mult == 1) - break; - fract_mult /= 10; - } - } else if (*buf == '\n') { - if (*(buf + 1) == '\0') - break; - else - return -EINVAL; - } else if (*buf == '.') { - integer_part = false; - } else { - return -EINVAL; - } - buf++; - } - if (negative) { - if (integer) - integer = -integer; - else - fract = -fract; - } - - ret = indio_dev->info->write_raw(indio_dev, this_attr->c, - integer, fract, this_attr->address); - if (ret) - return ret; - - return len; -} - -static -int __iio_device_attr_init(struct device_attribute *dev_attr, - const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*readfunc)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - bool generic) -{ - int ret; - char *name_format, *full_postfix; - sysfs_attr_init(&dev_attr->attr); - - /* Build up postfix of <extend_name>_<modifier>_postfix */ - if (chan->modified && !generic) { - if (chan->extend_name) - full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_modifier_names[chan - ->channel2], - chan->extend_name, - postfix); - else - full_postfix = kasprintf(GFP_KERNEL, "%s_%s", - iio_modifier_names[chan - ->channel2], - postfix); - } else { - if (chan->extend_name == NULL) - full_postfix = kstrdup(postfix, GFP_KERNEL); - else - full_postfix = kasprintf(GFP_KERNEL, - "%s_%s", - chan->extend_name, - postfix); - } - if (full_postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - if (chan->differential) { /* Differential can not have modifier */ - if (generic) - name_format - = kasprintf(GFP_KERNEL, "%s_%s-%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - iio_chan_type_name_spec[chan->type], - full_postfix); - else if (chan->indexed) - name_format - = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - chan->channel, - iio_chan_type_name_spec[chan->type], - chan->channel2, - full_postfix); - else { - WARN_ON("Differential channels must be indexed\n"); - ret = -EINVAL; - goto error_free_full_postfix; - } - } else { /* Single ended */ - if (generic) - name_format - = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - full_postfix); - else if (chan->indexed) - name_format - = kasprintf(GFP_KERNEL, "%s_%s%d_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - chan->channel, - full_postfix); - else - name_format - = kasprintf(GFP_KERNEL, "%s_%s_%s", - iio_direction[chan->output], - iio_chan_type_name_spec[chan->type], - full_postfix); - } - if (name_format == NULL) { - ret = -ENOMEM; - goto error_free_full_postfix; - } - dev_attr->attr.name = kasprintf(GFP_KERNEL, - name_format, - chan->channel, - chan->channel2); - if (dev_attr->attr.name == NULL) { - ret = -ENOMEM; - goto error_free_name_format; - } - - if (readfunc) { - dev_attr->attr.mode |= S_IRUGO; - dev_attr->show = readfunc; - } - - if (writefunc) { - dev_attr->attr.mode |= S_IWUSR; - dev_attr->store = writefunc; - } - kfree(name_format); - kfree(full_postfix); - - return 0; - -error_free_name_format: - kfree(name_format); -error_free_full_postfix: - kfree(full_postfix); -error_ret: - return ret; -} - -static void __iio_device_attr_deinit(struct device_attribute *dev_attr) -{ - kfree(dev_attr->attr.name); -} - -int __iio_add_chan_devattr(const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*readfunc)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - u64 mask, - bool generic, - struct device *dev, - struct list_head *attr_list) -{ - int ret; - struct iio_dev_attr *iio_attr, *t; - - iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL); - if (iio_attr == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_device_attr_init(&iio_attr->dev_attr, - postfix, chan, - readfunc, writefunc, generic); - if (ret) - goto error_iio_dev_attr_free; - iio_attr->c = chan; - iio_attr->address = mask; - list_for_each_entry(t, attr_list, l) - if (strcmp(t->dev_attr.attr.name, - iio_attr->dev_attr.attr.name) == 0) { - if (!generic) - dev_err(dev, "tried to double register : %s\n", - t->dev_attr.attr.name); - ret = -EBUSY; - goto error_device_attr_deinit; - } - list_add(&iio_attr->l, attr_list); - - return 0; - -error_device_attr_deinit: - __iio_device_attr_deinit(&iio_attr->dev_attr); -error_iio_dev_attr_free: - kfree(iio_attr); -error_ret: - return ret; -} - -static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret, i, attrcount = 0; - const struct iio_chan_spec_ext_info *ext_info; - - if (chan->channel < 0) - return 0; - - ret = __iio_add_chan_devattr(iio_data_type_name[chan->processed_val], - chan, - &iio_read_channel_info, - (chan->output ? - &iio_write_channel_info : NULL), - 0, - 0, - &indio_dev->dev, - &indio_dev->channel_attr_list); - if (ret) - goto error_ret; - attrcount++; - - for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) { - ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2], - chan, - &iio_read_channel_info, - &iio_write_channel_info, - i/2, - !(i%2), - &indio_dev->dev, - &indio_dev->channel_attr_list); - if (ret == -EBUSY && (i%2 == 0)) { - ret = 0; - continue; - } - if (ret < 0) - goto error_ret; - attrcount++; - } - - if (chan->ext_info) { - unsigned int i = 0; - for (ext_info = chan->ext_info; ext_info->name; ext_info++) { - ret = __iio_add_chan_devattr(ext_info->name, - chan, - ext_info->read ? - &iio_read_channel_ext_info : NULL, - ext_info->write ? - &iio_write_channel_ext_info : NULL, - i, - ext_info->shared, - &indio_dev->dev, - &indio_dev->channel_attr_list); - i++; - if (ret == -EBUSY && ext_info->shared) - continue; - - if (ret) - goto error_ret; - - attrcount++; - } - } - - ret = attrcount; -error_ret: - return ret; -} - -static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev, - struct iio_dev_attr *p) -{ - kfree(p->dev_attr.attr.name); - kfree(p); -} - -static ssize_t iio_show_dev_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", indio_dev->name); -} - -static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); - -static int iio_device_register_sysfs(struct iio_dev *indio_dev) -{ - int i, ret = 0, attrcount, attrn, attrcount_orig = 0; - struct iio_dev_attr *p, *n; - struct attribute **attr; - - /* First count elements in any existing group */ - if (indio_dev->info->attrs) { - attr = indio_dev->info->attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - /* - * New channel registration method - relies on the fact a group does - * not need to be initialized if it is name is NULL. - */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); - if (indio_dev->channels) - for (i = 0; i < indio_dev->num_channels; i++) { - ret = iio_device_add_channel_sysfs(indio_dev, - &indio_dev - ->channels[i]); - if (ret < 0) - goto error_clear_attrs; - attrcount += ret; - } - - if (indio_dev->name) - attrcount++; - - indio_dev->chan_attr_group.attrs = kcalloc(attrcount + 1, - sizeof(indio_dev->chan_attr_group.attrs[0]), - GFP_KERNEL); - if (indio_dev->chan_attr_group.attrs == NULL) { - ret = -ENOMEM; - goto error_clear_attrs; - } - /* Copy across original attributes */ - if (indio_dev->info->attrs) - memcpy(indio_dev->chan_attr_group.attrs, - indio_dev->info->attrs->attrs, - sizeof(indio_dev->chan_attr_group.attrs[0]) - *attrcount_orig); - attrn = attrcount_orig; - /* Add all elements from the list. */ - list_for_each_entry(p, &indio_dev->channel_attr_list, l) - indio_dev->chan_attr_group.attrs[attrn++] = &p->dev_attr.attr; - if (indio_dev->name) - indio_dev->chan_attr_group.attrs[attrn++] = &dev_attr_name.attr; - - indio_dev->groups[indio_dev->groupcounter++] = - &indio_dev->chan_attr_group; - - return 0; - -error_clear_attrs: - list_for_each_entry_safe(p, n, - &indio_dev->channel_attr_list, l) { - list_del(&p->l); - iio_device_remove_and_free_read_attr(indio_dev, p); - } - - return ret; -} - -static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) -{ - - struct iio_dev_attr *p, *n; - - list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) { - list_del(&p->l); - iio_device_remove_and_free_read_attr(indio_dev, p); - } - kfree(indio_dev->chan_attr_group.attrs); -} - -static void iio_dev_release(struct device *device) -{ - struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev); - cdev_del(&indio_dev->chrdev); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - iio_device_unregister_trigger_consumer(indio_dev); - iio_device_unregister_eventset(indio_dev); - iio_device_unregister_sysfs(indio_dev); - iio_device_unregister_debugfs(indio_dev); -} - -static struct device_type iio_dev_type = { - .name = "iio_device", - .release = iio_dev_release, -}; - -struct iio_dev *iio_allocate_device(int sizeof_priv) -{ - struct iio_dev *dev; - size_t alloc_size; - - alloc_size = sizeof(struct iio_dev); - if (sizeof_priv) { - alloc_size = ALIGN(alloc_size, IIO_ALIGN); - alloc_size += sizeof_priv; - } - /* ensure 32-byte alignment of whole construct ? */ - alloc_size += IIO_ALIGN - 1; - - dev = kzalloc(alloc_size, GFP_KERNEL); - - if (dev) { - dev->dev.groups = dev->groups; - dev->dev.type = &iio_dev_type; - dev->dev.bus = &iio_bus_type; - device_initialize(&dev->dev); - dev_set_drvdata(&dev->dev, (void *)dev); - mutex_init(&dev->mlock); - mutex_init(&dev->info_exist_lock); - - dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); - if (dev->id < 0) { - /* cannot use a dev_err as the name isn't available */ - printk(KERN_ERR "Failed to get id\n"); - kfree(dev); - return NULL; - } - dev_set_name(&dev->dev, "iio:device%d", dev->id); - } - - return dev; -} -EXPORT_SYMBOL(iio_allocate_device); - -void iio_free_device(struct iio_dev *dev) -{ - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } -} -EXPORT_SYMBOL(iio_free_device); - -/** - * iio_chrdev_open() - chrdev file open for buffer access and ioctls - **/ -static int iio_chrdev_open(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - - if (test_and_set_bit(IIO_BUSY_BIT_POS, &indio_dev->flags)) - return -EBUSY; - - filp->private_data = indio_dev; - - return 0; -} - -/** - * iio_chrdev_release() - chrdev file close buffer access and ioctls - **/ -static int iio_chrdev_release(struct inode *inode, struct file *filp) -{ - struct iio_dev *indio_dev = container_of(inode->i_cdev, - struct iio_dev, chrdev); - clear_bit(IIO_BUSY_BIT_POS, &indio_dev->flags); - return 0; -} - -/* Somewhat of a cross file organization violation - ioctls here are actually - * event related */ -static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct iio_dev *indio_dev = filp->private_data; - int __user *ip = (int __user *)arg; - int fd; - - if (cmd == IIO_GET_EVENT_FD_IOCTL) { - fd = iio_event_getfd(indio_dev); - if (copy_to_user(ip, &fd, sizeof(fd))) - return -EFAULT; - return 0; - } - return -EINVAL; -} - -static const struct file_operations iio_buffer_fileops = { - .read = iio_buffer_read_first_n_outer_addr, - .release = iio_chrdev_release, - .open = iio_chrdev_open, - .poll = iio_buffer_poll_addr, - .owner = THIS_MODULE, - .llseek = noop_llseek, - .unlocked_ioctl = iio_ioctl, - .compat_ioctl = iio_ioctl, -}; - -static const struct iio_buffer_setup_ops noop_ring_setup_ops; - -int iio_device_register(struct iio_dev *indio_dev) -{ - int ret; - - /* configure elements for the chrdev */ - indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); - - ret = iio_device_register_debugfs(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register debugfs interfaces\n"); - goto error_ret; - } - ret = iio_device_register_sysfs(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register sysfs interfaces\n"); - goto error_unreg_debugfs; - } - ret = iio_device_register_eventset(indio_dev); - if (ret) { - dev_err(indio_dev->dev.parent, - "Failed to register event set\n"); - goto error_free_sysfs; - } - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - iio_device_register_trigger_consumer(indio_dev); - - if ((indio_dev->modes & INDIO_ALL_BUFFER_MODES) && - indio_dev->setup_ops == NULL) - indio_dev->setup_ops = &noop_ring_setup_ops; - - ret = device_add(&indio_dev->dev); - if (ret < 0) - goto error_unreg_eventset; - cdev_init(&indio_dev->chrdev, &iio_buffer_fileops); - indio_dev->chrdev.owner = indio_dev->info->driver_module; - ret = cdev_add(&indio_dev->chrdev, indio_dev->dev.devt, 1); - if (ret < 0) - goto error_del_device; - return 0; - -error_del_device: - device_del(&indio_dev->dev); -error_unreg_eventset: - iio_device_unregister_eventset(indio_dev); -error_free_sysfs: - iio_device_unregister_sysfs(indio_dev); -error_unreg_debugfs: - iio_device_unregister_debugfs(indio_dev); -error_ret: - return ret; -} -EXPORT_SYMBOL(iio_device_register); - -void iio_device_unregister(struct iio_dev *indio_dev) -{ - mutex_lock(&indio_dev->info_exist_lock); - indio_dev->info = NULL; - mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); -} -EXPORT_SYMBOL(iio_device_unregister); -subsys_initcall(iio_init); -module_exit(iio_exit); - -MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>"); -MODULE_DESCRIPTION("Industrial I/O core"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c deleted file mode 100644 index 5fdf739..0000000 --- a/drivers/staging/iio/industrialio-event.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Industrial I/O event handling - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Based on elements of hwmon and input subsystems. - */ - -#include <linux/anon_inodes.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/kfifo.h> -#include <linux/module.h> -#include <linux/poll.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/uaccess.h> -#include <linux/wait.h> -#include "iio.h" -#include "iio_core.h" -#include "sysfs.h" -#include "events.h" - -/** - * struct iio_event_interface - chrdev interface for an event line - * @wait: wait queue to allow blocking reads of events - * @det_events: list of detected events - * @dev_attr_list: list of event interface sysfs attribute - * @flags: file operations related flags including busy flag. - * @group: event interface sysfs attribute group - */ -struct iio_event_interface { - wait_queue_head_t wait; - DECLARE_KFIFO(det_events, struct iio_event_data, 16); - - struct list_head dev_attr_list; - unsigned long flags; - struct attribute_group group; -}; - -int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) -{ - struct iio_event_interface *ev_int = indio_dev->event_interface; - struct iio_event_data ev; - int copied; - - /* Does anyone care? */ - spin_lock(&ev_int->wait.lock); - if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - - ev.id = ev_code; - ev.timestamp = timestamp; - - copied = kfifo_put(&ev_int->det_events, &ev); - if (copied != 0) - wake_up_locked_poll(&ev_int->wait, POLLIN); - } - spin_unlock(&ev_int->wait.lock); - - return 0; -} -EXPORT_SYMBOL(iio_push_event); - -/** - * iio_event_poll() - poll the event queue to find out if it has data - */ -static unsigned int iio_event_poll(struct file *filep, - struct poll_table_struct *wait) -{ - struct iio_event_interface *ev_int = filep->private_data; - unsigned int events = 0; - - poll_wait(filep, &ev_int->wait, wait); - - spin_lock(&ev_int->wait.lock); - if (!kfifo_is_empty(&ev_int->det_events)) - events = POLLIN | POLLRDNORM; - spin_unlock(&ev_int->wait.lock); - - return events; -} - -static ssize_t iio_event_chrdev_read(struct file *filep, - char __user *buf, - size_t count, - loff_t *f_ps) -{ - struct iio_event_interface *ev_int = filep->private_data; - unsigned int copied; - int ret; - - if (count < sizeof(struct iio_event_data)) - return -EINVAL; - - spin_lock(&ev_int->wait.lock); - if (kfifo_is_empty(&ev_int->det_events)) { - if (filep->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - goto error_unlock; - } - /* Blocking on device; waiting for something to be there */ - ret = wait_event_interruptible_locked(ev_int->wait, - !kfifo_is_empty(&ev_int->det_events)); - if (ret) - goto error_unlock; - /* Single access device so no one else can get the data */ - } - - ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied); - -error_unlock: - spin_unlock(&ev_int->wait.lock); - - return ret ? ret : copied; -} - -static int iio_event_chrdev_release(struct inode *inode, struct file *filep) -{ - struct iio_event_interface *ev_int = filep->private_data; - - spin_lock(&ev_int->wait.lock); - __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - /* - * In order to maintain a clean state for reopening, - * clear out any awaiting events. The mask will prevent - * any new __iio_push_event calls running. - */ - kfifo_reset_out(&ev_int->det_events); - spin_unlock(&ev_int->wait.lock); - - return 0; -} - -static const struct file_operations iio_event_chrdev_fileops = { - .read = iio_event_chrdev_read, - .poll = iio_event_poll, - .release = iio_event_chrdev_release, - .owner = THIS_MODULE, - .llseek = noop_llseek, -}; - -int iio_event_getfd(struct iio_dev *indio_dev) -{ - struct iio_event_interface *ev_int = indio_dev->event_interface; - int fd; - - if (ev_int == NULL) - return -ENODEV; - - spin_lock(&ev_int->wait.lock); - if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) { - spin_unlock(&ev_int->wait.lock); - return -EBUSY; - } - spin_unlock(&ev_int->wait.lock); - fd = anon_inode_getfd("iio:event", - &iio_event_chrdev_fileops, ev_int, O_RDONLY); - if (fd < 0) { - spin_lock(&ev_int->wait.lock); - __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - spin_unlock(&ev_int->wait.lock); - } - return fd; -} - -static const char * const iio_ev_type_text[] = { - [IIO_EV_TYPE_THRESH] = "thresh", - [IIO_EV_TYPE_MAG] = "mag", - [IIO_EV_TYPE_ROC] = "roc", - [IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive", - [IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive", -}; - -static const char * const iio_ev_dir_text[] = { - [IIO_EV_DIR_EITHER] = "either", - [IIO_EV_DIR_RISING] = "rising", - [IIO_EV_DIR_FALLING] = "falling" -}; - -static ssize_t iio_ev_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret; - bool val; - - ret = strtobool(buf, &val); - if (ret < 0) - return ret; - - ret = indio_dev->info->write_event_config(indio_dev, - this_attr->address, - val); - return (ret < 0) ? ret : len; -} - -static ssize_t iio_ev_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val = indio_dev->info->read_event_config(indio_dev, - this_attr->address); - - if (val < 0) - return val; - else - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int val, ret; - - ret = indio_dev->info->read_event_value(indio_dev, - this_attr->address, &val); - if (ret < 0) - return ret; - - return sprintf(buf, "%d\n", val); -} - -static ssize_t iio_ev_value_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned long val; - int ret; - - if (!indio_dev->info->write_event_value) - return -EINVAL; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return ret; - - ret = indio_dev->info->write_event_value(indio_dev, this_attr->address, - val); - if (ret < 0) - return ret; - - return len; -} - -static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret = 0, i, attrcount = 0; - u64 mask = 0; - char *postfix; - if (!chan->event_mask) - return 0; - - for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { - postfix = kasprintf(GFP_KERNEL, "%s_%s_en", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - if (chan->modified) - mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - else if (chan->differential) - mask = IIO_EVENT_CODE(chan->type, - 0, 0, - i%IIO_EV_DIR_MAX, - i/IIO_EV_DIR_MAX, - 0, - chan->channel, - chan->channel2); - else - mask = IIO_UNMOD_EVENT_CODE(chan->type, - chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - - ret = __iio_add_chan_devattr(postfix, - chan, - &iio_ev_state_show, - iio_ev_state_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - postfix = kasprintf(GFP_KERNEL, "%s_%s_value", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_add_chan_devattr(postfix, chan, - iio_ev_value_show, - iio_ev_value_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - } - ret = attrcount; -error_ret: - return ret; -} - -static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p, *n; - list_for_each_entry_safe(p, n, - &indio_dev->event_interface-> - dev_attr_list, l) { - kfree(p->dev_attr.attr.name); - kfree(p); - } -} - -static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) -{ - int j, ret, attrcount = 0; - - INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list); - /* Dynically created from the channels array */ - for (j = 0; j < indio_dev->num_channels; j++) { - ret = iio_device_add_event_sysfs(indio_dev, - &indio_dev->channels[j]); - if (ret < 0) - goto error_clear_attrs; - attrcount += ret; - } - return attrcount; - -error_clear_attrs: - __iio_remove_event_config_attrs(indio_dev); - - return ret; -} - -static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) -{ - int j; - - for (j = 0; j < indio_dev->num_channels; j++) - if (indio_dev->channels[j].event_mask != 0) - return true; - return false; -} - -static void iio_setup_ev_int(struct iio_event_interface *ev_int) -{ - INIT_KFIFO(ev_int->det_events); - init_waitqueue_head(&ev_int->wait); -} - -static const char *iio_event_group_name = "events"; -int iio_device_register_eventset(struct iio_dev *indio_dev) -{ - struct iio_dev_attr *p; - int ret = 0, attrcount_orig = 0, attrcount, attrn; - struct attribute **attr; - - if (!(indio_dev->info->event_attrs || - iio_check_for_dynamic_events(indio_dev))) - return 0; - - indio_dev->event_interface = - kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL); - if (indio_dev->event_interface == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - iio_setup_ev_int(indio_dev->event_interface); - if (indio_dev->info->event_attrs != NULL) { - attr = indio_dev->info->event_attrs->attrs; - while (*attr++ != NULL) - attrcount_orig++; - } - attrcount = attrcount_orig; - if (indio_dev->channels) { - ret = __iio_add_event_config_attrs(indio_dev); - if (ret < 0) - goto error_free_setup_event_lines; - attrcount += ret; - } - - indio_dev->event_interface->group.name = iio_event_group_name; - indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1, - sizeof(indio_dev->event_interface->group.attrs[0]), - GFP_KERNEL); - if (indio_dev->event_interface->group.attrs == NULL) { - ret = -ENOMEM; - goto error_free_setup_event_lines; - } - if (indio_dev->info->event_attrs) - memcpy(indio_dev->event_interface->group.attrs, - indio_dev->info->event_attrs->attrs, - sizeof(indio_dev->event_interface->group.attrs[0]) - *attrcount_orig); - attrn = attrcount_orig; - /* Add all elements from the list. */ - list_for_each_entry(p, - &indio_dev->event_interface->dev_attr_list, - l) - indio_dev->event_interface->group.attrs[attrn++] = - &p->dev_attr.attr; - indio_dev->groups[indio_dev->groupcounter++] = - &indio_dev->event_interface->group; - - return 0; - -error_free_setup_event_lines: - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface); -error_ret: - - return ret; -} - -void iio_device_unregister_eventset(struct iio_dev *indio_dev) -{ - if (indio_dev->event_interface == NULL) - return; - __iio_remove_event_config_attrs(indio_dev); - kfree(indio_dev->event_interface->group.attrs); - kfree(indio_dev->event_interface); -} diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c deleted file mode 100644 index 47ecadd..0000000 --- a/drivers/staging/iio/industrialio-trigger.c +++ /dev/null @@ -1,509 +0,0 @@ -/* The industrial I/O core, trigger handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include <linux/kernel.h> -#include <linux/idr.h> -#include <linux/err.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/list.h> -#include <linux/slab.h> - -#include "iio.h" -#include "trigger.h" -#include "iio_core.h" -#include "iio_core_trigger.h" -#include "trigger_consumer.h" - -/* RFC - Question of approach - * Make the common case (single sensor single trigger) - * simple by starting trigger capture from when first sensors - * is added. - * - * Complex simultaneous start requires use of 'hold' functionality - * of the trigger. (not implemented) - * - * Any other suggestions? - */ - -static DEFINE_IDA(iio_trigger_ida); - -/* Single list of all available triggers */ -static LIST_HEAD(iio_trigger_list); -static DEFINE_MUTEX(iio_trigger_list_lock); - -/** - * iio_trigger_read_name() - retrieve useful identifying name - **/ -static ssize_t iio_trigger_read_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_trigger *trig = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", trig->name); -} - -static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); - -/** - * iio_trigger_register_sysfs() - create a device for this trigger - * @trig_info: the trigger - * - * Also adds any control attribute registered by the trigger driver - **/ -static int iio_trigger_register_sysfs(struct iio_trigger *trig_info) -{ - return sysfs_add_file_to_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} - -static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info) -{ - sysfs_remove_file_from_group(&trig_info->dev.kobj, - &dev_attr_name.attr, - NULL); -} - -int iio_trigger_register(struct iio_trigger *trig_info) -{ - int ret; - - trig_info->id = ida_simple_get(&iio_trigger_ida, 0, 0, GFP_KERNEL); - if (trig_info->id < 0) { - ret = trig_info->id; - goto error_ret; - } - /* Set the name used for the sysfs directory etc */ - dev_set_name(&trig_info->dev, "trigger%ld", - (unsigned long) trig_info->id); - - ret = device_add(&trig_info->dev); - if (ret) - goto error_unregister_id; - - ret = iio_trigger_register_sysfs(trig_info); - if (ret) - goto error_device_del; - - /* Add to list of available triggers held by the IIO core */ - mutex_lock(&iio_trigger_list_lock); - list_add_tail(&trig_info->list, &iio_trigger_list); - mutex_unlock(&iio_trigger_list_lock); - - return 0; - -error_device_del: - device_del(&trig_info->dev); -error_unregister_id: - ida_simple_remove(&iio_trigger_ida, trig_info->id); -error_ret: - return ret; -} -EXPORT_SYMBOL(iio_trigger_register); - -void iio_trigger_unregister(struct iio_trigger *trig_info) -{ - mutex_lock(&iio_trigger_list_lock); - list_del(&trig_info->list); - mutex_unlock(&iio_trigger_list_lock); - - iio_trigger_unregister_sysfs(trig_info); - ida_simple_remove(&iio_trigger_ida, trig_info->id); - /* Possible issue in here */ - device_unregister(&trig_info->dev); -} -EXPORT_SYMBOL(iio_trigger_unregister); - -static struct iio_trigger *iio_trigger_find_by_name(const char *name, - size_t len) -{ - struct iio_trigger *trig = NULL, *iter; - - mutex_lock(&iio_trigger_list_lock); - list_for_each_entry(iter, &iio_trigger_list, list) - if (sysfs_streq(iter->name, name)) { - trig = iter; - break; - } - mutex_unlock(&iio_trigger_list_lock); - - return trig; -} - -void iio_trigger_poll(struct iio_trigger *trig, s64 time) -{ - int i; - if (!trig->use_count) - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) - if (trig->subirqs[i].enabled) { - trig->use_count++; - generic_handle_irq(trig->subirq_base + i); - } -} -EXPORT_SYMBOL(iio_trigger_poll); - -irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private) -{ - iio_trigger_poll(private, iio_get_time_ns()); - return IRQ_HANDLED; -} -EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll); - -void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time) -{ - int i; - if (!trig->use_count) - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) - if (trig->subirqs[i].enabled) { - trig->use_count++; - handle_nested_irq(trig->subirq_base + i); - } -} -EXPORT_SYMBOL(iio_trigger_poll_chained); - -void iio_trigger_notify_done(struct iio_trigger *trig) -{ - trig->use_count--; - if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) - if (trig->ops->try_reenable(trig)) - /* Missed and interrupt so launch new poll now */ - iio_trigger_poll(trig, 0); -} -EXPORT_SYMBOL(iio_trigger_notify_done); - -/* Trigger Consumer related functions */ -static int iio_trigger_get_irq(struct iio_trigger *trig) -{ - int ret; - mutex_lock(&trig->pool_lock); - ret = bitmap_find_free_region(trig->pool, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - ilog2(1)); - mutex_unlock(&trig->pool_lock); - if (ret >= 0) - ret += trig->subirq_base; - - return ret; -} - -static void iio_trigger_put_irq(struct iio_trigger *trig, int irq) -{ - mutex_lock(&trig->pool_lock); - clear_bit(irq - trig->subirq_base, trig->pool); - mutex_unlock(&trig->pool_lock); -} - -/* Complexity in here. With certain triggers (datardy) an acknowledgement - * may be needed if the pollfuncs do not include the data read for the - * triggering device. - * This is not currently handled. Alternative of not enabling trigger unless - * the relevant function is in there may be the best option. - */ -/* Worth protecting against double additions?*/ -static int iio_trigger_attach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) -{ - int ret = 0; - bool notinuse - = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); - - /* Prevent the module being removed whilst attached to a trigger */ - __module_get(pf->indio_dev->info->driver_module); - pf->irq = iio_trigger_get_irq(trig); - ret = request_threaded_irq(pf->irq, pf->h, pf->thread, - pf->type, pf->name, - pf); - if (ret < 0) { - module_put(pf->indio_dev->info->driver_module); - return ret; - } - - if (trig->ops && trig->ops->set_trigger_state && notinuse) { - ret = trig->ops->set_trigger_state(trig, true); - if (ret < 0) - module_put(pf->indio_dev->info->driver_module); - } - - return ret; -} - -static int iio_trigger_dettach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) -{ - int ret = 0; - bool no_other_users - = (bitmap_weight(trig->pool, - CONFIG_IIO_CONSUMERS_PER_TRIGGER) - == 1); - if (trig->ops && trig->ops->set_trigger_state && no_other_users) { - ret = trig->ops->set_trigger_state(trig, false); - if (ret) - goto error_ret; - } - iio_trigger_put_irq(trig, pf->irq); - free_irq(pf->irq, pf); - module_put(pf->indio_dev->info->driver_module); - -error_ret: - return ret; -} - -irqreturn_t iio_pollfunc_store_time(int irq, void *p) -{ - struct iio_poll_func *pf = p; - pf->timestamp = iio_get_time_ns(); - return IRQ_WAKE_THREAD; -} -EXPORT_SYMBOL(iio_pollfunc_store_time); - -struct iio_poll_func -*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), - irqreturn_t (*thread)(int irq, void *p), - int type, - struct iio_dev *indio_dev, - const char *fmt, - ...) -{ - va_list vargs; - struct iio_poll_func *pf; - - pf = kmalloc(sizeof *pf, GFP_KERNEL); - if (pf == NULL) - return NULL; - va_start(vargs, fmt); - pf->name = kvasprintf(GFP_KERNEL, fmt, vargs); - va_end(vargs); - if (pf->name == NULL) { - kfree(pf); - return NULL; - } - pf->h = h; - pf->thread = thread; - pf->type = type; - pf->indio_dev = indio_dev; - - return pf; -} -EXPORT_SYMBOL_GPL(iio_alloc_pollfunc); - -void iio_dealloc_pollfunc(struct iio_poll_func *pf) -{ - kfree(pf->name); - kfree(pf); -} -EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc); - -/** - * iio_trigger_read_current() - trigger consumer sysfs query which trigger - * - * For trigger consumers the current_trigger interface allows the trigger - * used by the device to be queried. - **/ -static ssize_t iio_trigger_read_current(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - if (indio_dev->trig) - return sprintf(buf, "%s\n", indio_dev->trig->name); - return 0; -} - -/** - * iio_trigger_write_current() trigger consumer sysfs set current trigger - * - * For trigger consumers the current_trigger interface allows the trigger - * used for this device to be specified at run time based on the triggers - * name. - **/ -static ssize_t iio_trigger_write_current(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct iio_trigger *oldtrig = indio_dev->trig; - struct iio_trigger *trig; - int ret; - - mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { - mutex_unlock(&indio_dev->mlock); - return -EBUSY; - } - mutex_unlock(&indio_dev->mlock); - - trig = iio_trigger_find_by_name(buf, len); - if (oldtrig == trig) - return len; - - if (trig && indio_dev->info->validate_trigger) { - ret = indio_dev->info->validate_trigger(indio_dev, trig); - if (ret) - return ret; - } - - if (trig && trig->ops && trig->ops->validate_device) { - ret = trig->ops->validate_device(trig, indio_dev); - if (ret) - return ret; - } - - indio_dev->trig = trig; - - if (oldtrig && indio_dev->trig != oldtrig) - iio_put_trigger(oldtrig); - if (indio_dev->trig) - iio_get_trigger(indio_dev->trig); - - return len; -} - -static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR, - iio_trigger_read_current, - iio_trigger_write_current); - -static struct attribute *iio_trigger_consumer_attrs[] = { - &dev_attr_current_trigger.attr, - NULL, -}; - -static const struct attribute_group iio_trigger_consumer_attr_group = { - .name = "trigger", - .attrs = iio_trigger_consumer_attrs, -}; - -static void iio_trig_release(struct device *device) -{ - struct iio_trigger *trig = to_iio_trigger(device); - int i; - - if (trig->subirq_base) { - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_modify_status(trig->subirq_base + i, - IRQ_NOAUTOEN, - IRQ_NOREQUEST | IRQ_NOPROBE); - irq_set_chip(trig->subirq_base + i, - NULL); - irq_set_handler(trig->subirq_base + i, - NULL); - } - - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - } - kfree(trig->name); - kfree(trig); -} - -static struct device_type iio_trig_type = { - .release = iio_trig_release, -}; - -static void iio_trig_subirqmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_trigger *trig - = container_of(chip, - struct iio_trigger, subirq_chip); - trig->subirqs[d->irq - trig->subirq_base].enabled = false; -} - -static void iio_trig_subirqunmask(struct irq_data *d) -{ - struct irq_chip *chip = irq_data_get_irq_chip(d); - struct iio_trigger *trig - = container_of(chip, - struct iio_trigger, subirq_chip); - trig->subirqs[d->irq - trig->subirq_base].enabled = true; -} - -struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) -{ - va_list vargs; - struct iio_trigger *trig; - trig = kzalloc(sizeof *trig, GFP_KERNEL); - if (trig) { - int i; - trig->dev.type = &iio_trig_type; - trig->dev.bus = &iio_bus_type; - device_initialize(&trig->dev); - dev_set_drvdata(&trig->dev, (void *)trig); - - mutex_init(&trig->pool_lock); - trig->subirq_base - = irq_alloc_descs(-1, 0, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - 0); - if (trig->subirq_base < 0) { - kfree(trig); - return NULL; - } - va_start(vargs, fmt); - trig->name = kvasprintf(GFP_KERNEL, fmt, vargs); - va_end(vargs); - if (trig->name == NULL) { - irq_free_descs(trig->subirq_base, - CONFIG_IIO_CONSUMERS_PER_TRIGGER); - kfree(trig); - return NULL; - } - trig->subirq_chip.name = trig->name; - trig->subirq_chip.irq_mask = &iio_trig_subirqmask; - trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask; - for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) { - irq_set_chip(trig->subirq_base + i, - &trig->subirq_chip); - irq_set_handler(trig->subirq_base + i, - &handle_simple_irq); - irq_modify_status(trig->subirq_base + i, - IRQ_NOREQUEST | IRQ_NOAUTOEN, - IRQ_NOPROBE); - } - get_device(&trig->dev); - } - return trig; -} -EXPORT_SYMBOL(iio_allocate_trigger); - -void iio_free_trigger(struct iio_trigger *trig) -{ - if (trig) - put_device(&trig->dev); -} -EXPORT_SYMBOL(iio_free_trigger); - -void iio_device_register_trigger_consumer(struct iio_dev *indio_dev) -{ - indio_dev->groups[indio_dev->groupcounter++] = - &iio_trigger_consumer_attr_group; -} - -void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev) -{ - /* Clean up and associated but not attached triggers references */ - if (indio_dev->trig) - iio_put_trigger(indio_dev->trig); -} - -int iio_triggered_buffer_postenable(struct iio_dev *indio_dev) -{ - return iio_trigger_attach_poll_func(indio_dev->trig, - indio_dev->pollfunc); -} -EXPORT_SYMBOL(iio_triggered_buffer_postenable); - -int iio_triggered_buffer_predisable(struct iio_dev *indio_dev) -{ - return iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); -} -EXPORT_SYMBOL(iio_triggered_buffer_predisable); diff --git a/drivers/staging/iio/inkern.c b/drivers/staging/iio/inkern.c deleted file mode 100644 index ef07a02..0000000 --- a/drivers/staging/iio/inkern.c +++ /dev/null @@ -1,293 +0,0 @@ -/* The industrial I/O core in kernel channel mapping - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include <linux/err.h> -#include <linux/export.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include "iio.h" -#include "iio_core.h" -#include "machine.h" -#include "driver.h" -#include "consumer.h" - -struct iio_map_internal { - struct iio_dev *indio_dev; - struct iio_map *map; - struct list_head l; -}; - -static LIST_HEAD(iio_map_list); -static DEFINE_MUTEX(iio_map_list_lock); - -int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps) -{ - int i = 0, ret = 0; - struct iio_map_internal *mapi; - - if (maps == NULL) - return 0; - - mutex_lock(&iio_map_list_lock); - while (maps[i].consumer_dev_name != NULL) { - mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); - if (mapi == NULL) { - ret = -ENOMEM; - goto error_ret; - } - mapi->map = &maps[i]; - mapi->indio_dev = indio_dev; - list_add(&mapi->l, &iio_map_list); - i++; - } -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_map_array_register); - - -/* Assumes the exact same array (e.g. memory locations) - * used at unregistration as used at registration rather than - * more complex checking of contents. - */ -int iio_map_array_unregister(struct iio_dev *indio_dev, - struct iio_map *maps) -{ - int i = 0, ret = 0; - bool found_it; - struct iio_map_internal *mapi; - - if (maps == NULL) - return 0; - - mutex_lock(&iio_map_list_lock); - while (maps[i].consumer_dev_name != NULL) { - found_it = false; - list_for_each_entry(mapi, &iio_map_list, l) - if (&maps[i] == mapi->map) { - list_del(&mapi->l); - kfree(mapi); - found_it = true; - break; - } - if (found_it == false) { - ret = -ENODEV; - goto error_ret; - } - i++; - } -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_map_array_unregister); - -static const struct iio_chan_spec -*iio_chan_spec_from_name(const struct iio_dev *indio_dev, - const char *name) -{ - int i; - const struct iio_chan_spec *chan = NULL; - - for (i = 0; i < indio_dev->num_channels; i++) - if (indio_dev->channels[i].datasheet_name && - strcmp(name, indio_dev->channels[i].datasheet_name) == 0) { - chan = &indio_dev->channels[i]; - break; - } - return chan; -} - - -struct iio_channel *iio_st_channel_get(const char *name, - const char *channel_name) -{ - struct iio_map_internal *c_i = NULL, *c = NULL; - struct iio_channel *channel; - - if (name == NULL && channel_name == NULL) - return ERR_PTR(-ENODEV); - - /* first find matching entry the channel map */ - mutex_lock(&iio_map_list_lock); - list_for_each_entry(c_i, &iio_map_list, l) { - if ((name && strcmp(name, c_i->map->consumer_dev_name) != 0) || - (channel_name && - strcmp(channel_name, c_i->map->consumer_channel) != 0)) - continue; - c = c_i; - get_device(&c->indio_dev->dev); - break; - } - mutex_unlock(&iio_map_list_lock); - if (c == NULL) - return ERR_PTR(-ENODEV); - - channel = kmalloc(sizeof(*channel), GFP_KERNEL); - if (channel == NULL) - return ERR_PTR(-ENOMEM); - - channel->indio_dev = c->indio_dev; - - if (c->map->adc_channel_label) - channel->channel = - iio_chan_spec_from_name(channel->indio_dev, - c->map->adc_channel_label); - - return channel; -} -EXPORT_SYMBOL_GPL(iio_st_channel_get); - -void iio_st_channel_release(struct iio_channel *channel) -{ - put_device(&channel->indio_dev->dev); - kfree(channel); -} -EXPORT_SYMBOL_GPL(iio_st_channel_release); - -struct iio_channel *iio_st_channel_get_all(const char *name) -{ - struct iio_channel *chans; - struct iio_map_internal *c = NULL; - int nummaps = 0; - int mapind = 0; - int i, ret; - - if (name == NULL) - return ERR_PTR(-EINVAL); - - mutex_lock(&iio_map_list_lock); - /* first count the matching maps */ - list_for_each_entry(c, &iio_map_list, l) - if (name && strcmp(name, c->map->consumer_dev_name) != 0) - continue; - else - nummaps++; - - if (nummaps == 0) { - ret = -ENODEV; - goto error_ret; - } - - /* NULL terminated array to save passing size */ - chans = kzalloc(sizeof(*chans)*(nummaps + 1), GFP_KERNEL); - if (chans == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - /* for each map fill in the chans element */ - list_for_each_entry(c, &iio_map_list, l) { - if (name && strcmp(name, c->map->consumer_dev_name) != 0) - continue; - chans[mapind].indio_dev = c->indio_dev; - chans[mapind].channel = - iio_chan_spec_from_name(chans[mapind].indio_dev, - c->map->adc_channel_label); - if (chans[mapind].channel == NULL) { - ret = -EINVAL; - put_device(&chans[mapind].indio_dev->dev); - goto error_free_chans; - } - get_device(&chans[mapind].indio_dev->dev); - mapind++; - } - mutex_unlock(&iio_map_list_lock); - if (mapind == 0) { - ret = -ENODEV; - goto error_free_chans; - } - return chans; - -error_free_chans: - for (i = 0; i < nummaps; i++) - if (chans[i].indio_dev) - put_device(&chans[i].indio_dev->dev); - kfree(chans); -error_ret: - mutex_unlock(&iio_map_list_lock); - - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(iio_st_channel_get_all); - -void iio_st_channel_release_all(struct iio_channel *channels) -{ - struct iio_channel *chan = &channels[0]; - - while (chan->indio_dev) { - put_device(&chan->indio_dev->dev); - chan++; - } - kfree(channels); -} -EXPORT_SYMBOL_GPL(iio_st_channel_release_all); - -int iio_st_read_channel_raw(struct iio_channel *chan, int *val) -{ - int val2, ret; - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - ret = chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, - val, &val2, 0); -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_read_channel_raw); - -int iio_st_read_channel_scale(struct iio_channel *chan, int *val, int *val2) -{ - int ret; - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - ret = chan->indio_dev->info->read_raw(chan->indio_dev, - chan->channel, - val, val2, - IIO_CHAN_INFO_SCALE); -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_read_channel_scale); - -int iio_st_get_channel_type(struct iio_channel *chan, - enum iio_chan_type *type) -{ - int ret = 0; - /* Need to verify underlying driver has not gone away */ - - mutex_lock(&chan->indio_dev->info_exist_lock); - if (chan->indio_dev->info == NULL) { - ret = -ENODEV; - goto err_unlock; - } - - *type = chan->channel->type; -err_unlock: - mutex_unlock(&chan->indio_dev->info_exist_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(iio_st_get_channel_type); diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c deleted file mode 100644 index 9f3bd59..0000000 --- a/drivers/staging/iio/kfifo_buf.c +++ /dev/null @@ -1,151 +0,0 @@ -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/workqueue.h> -#include <linux/kfifo.h> -#include <linux/mutex.h> - -#include "kfifo_buf.h" - -struct iio_kfifo { - struct iio_buffer buffer; - struct kfifo kf; - int update_needed; -}; - -#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer) - -static inline int __iio_allocate_kfifo(struct iio_kfifo *buf, - int bytes_per_datum, int length) -{ - if ((length == 0) || (bytes_per_datum == 0)) - return -EINVAL; - - __iio_update_buffer(&buf->buffer, bytes_per_datum, length); - return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL); -} - -static int iio_request_update_kfifo(struct iio_buffer *r) -{ - int ret = 0; - struct iio_kfifo *buf = iio_to_kfifo(r); - - if (!buf->update_needed) - goto error_ret; - kfifo_free(&buf->kf); - ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum, - buf->buffer.length); -error_ret: - return ret; -} - -static int iio_get_length_kfifo(struct iio_buffer *r) -{ - return r->length; -} - -static IIO_BUFFER_ENABLE_ATTR; -static IIO_BUFFER_LENGTH_ATTR; - -static struct attribute *iio_kfifo_attributes[] = { - &dev_attr_length.attr, - &dev_attr_enable.attr, - NULL, -}; - -static struct attribute_group iio_kfifo_attribute_group = { - .attrs = iio_kfifo_attributes, - .name = "buffer", -}; - -static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r) -{ - return r->bytes_per_datum; -} - -static int iio_mark_update_needed_kfifo(struct iio_buffer *r) -{ - struct iio_kfifo *kf = iio_to_kfifo(r); - kf->update_needed = true; - return 0; -} - -static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd) -{ - if (r->bytes_per_datum != bpd) { - r->bytes_per_datum = bpd; - iio_mark_update_needed_kfifo(r); - } - return 0; -} - -static int iio_set_length_kfifo(struct iio_buffer *r, int length) -{ - if (r->length != length) { - r->length = length; - iio_mark_update_needed_kfifo(r); - } - return 0; -} - -static int iio_store_to_kfifo(struct iio_buffer *r, - u8 *data, - s64 timestamp) -{ - int ret; - struct iio_kfifo *kf = iio_to_kfifo(r); - ret = kfifo_in(&kf->kf, data, r->bytes_per_datum); - if (ret != r->bytes_per_datum) - return -EBUSY; - return 0; -} - -static int iio_read_first_n_kfifo(struct iio_buffer *r, - size_t n, char __user *buf) -{ - int ret, copied; - struct iio_kfifo *kf = iio_to_kfifo(r); - - if (n < r->bytes_per_datum) - return -EINVAL; - - n = rounddown(n, r->bytes_per_datum); - ret = kfifo_to_user(&kf->kf, buf, n, &copied); - - return copied; -} - -static const struct iio_buffer_access_funcs kfifo_access_funcs = { - .store_to = &iio_store_to_kfifo, - .read_first_n = &iio_read_first_n_kfifo, - .request_update = &iio_request_update_kfifo, - .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo, - .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, - .get_length = &iio_get_length_kfifo, - .set_length = &iio_set_length_kfifo, -}; - -struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) -{ - struct iio_kfifo *kf; - - kf = kzalloc(sizeof *kf, GFP_KERNEL); - if (!kf) - return NULL; - kf->update_needed = true; - iio_buffer_init(&kf->buffer); - kf->buffer.attrs = &iio_kfifo_attribute_group; - kf->buffer.access = &kfifo_access_funcs; - - return &kf->buffer; -} -EXPORT_SYMBOL(iio_kfifo_allocate); - -void iio_kfifo_free(struct iio_buffer *r) -{ - kfree(iio_to_kfifo(r)); -} -EXPORT_SYMBOL(iio_kfifo_free); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h deleted file mode 100644 index 9f7da01..0000000 --- a/drivers/staging/iio/kfifo_buf.h +++ /dev/null @@ -1,8 +0,0 @@ - -#include <linux/kfifo.h> -#include "iio.h" -#include "buffer.h" - -struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); -void iio_kfifo_free(struct iio_buffer *r); - diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index e7e9159..4bed30e 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -4,15 +4,26 @@ menu "Light sensors" config SENSORS_ISL29018 - tristate "ISL 29018 light and proximity sensor" - depends on I2C - default n - help - If you say yes here you get support for ambient light sensing and - proximity infrared sensing from Intersil ISL29018. - This driver will provide the measurements of ambient light intensity - in lux, proximity infrared sensing and normal infrared sensing. - Data from sensor is accessible via sysfs. + tristate "ISL 29018 light and proximity sensor" + depends on I2C + select REGMAP_I2C + default n + help + If you say yes here you get support for ambient light sensing and + proximity infrared sensing from Intersil ISL29018. + This driver will provide the measurements of ambient light intensity + in lux, proximity infrared sensing and normal infrared sensing. + Data from sensor is accessible via sysfs. + +config SENSORS_ISL29028 + tristate "Intersil ISL29028 Concurrent Light and Proximity Sensor" + depends on I2C + select REGMAP_I2C + help + Provides driver for the Intersil's ISL29028 device. + This driver supports the sysfs interface to get the ALS, IR intensity, + Proximity value via iio. The ISL29028 provides the concurrent sensing + of ambient light and proximity. config SENSORS_TSL2563 tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors" @@ -31,4 +42,12 @@ config TSL2583 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices. Access ALS data via iio, sysfs. +config TSL2x7x + tristate "TAOS TSL/TMD2x71 and TSL/TMD2x72 Family of light and proximity sensors" + depends on I2C + help + Support for: tsl2571, tsl2671, tmd2671, tsl2771, tmd2771, tsl2572, tsl2672, + tmd2672, tsl2772, tmd2772 devices. + Provides iio_events and direct access via sysfs. + endmenu diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile index 3011fbf..141af1e 100644 --- a/drivers/staging/iio/light/Makefile +++ b/drivers/staging/iio/light/Makefile @@ -4,4 +4,6 @@ obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o obj-$(CONFIG_SENSORS_ISL29018) += isl29018.o +obj-$(CONFIG_SENSORS_ISL29028) += isl29028.o obj-$(CONFIG_TSL2583) += tsl2583.o +obj-$(CONFIG_TSL2x7x) += tsl2x7x_core.o diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 38ec52b6..0abbf18 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -26,9 +26,11 @@ #include <linux/err.h> #include <linux/mutex.h> #include <linux/delay.h> +#include <linux/regmap.h> #include <linux/slab.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + #define CONVERSION_TIME_MS 100 #define ISL29018_REG_ADD_COMMAND1 0x00 @@ -51,49 +53,22 @@ #define ISL29018_REG_ADD_DATA_LSB 0x02 #define ISL29018_REG_ADD_DATA_MSB 0x03 -#define ISL29018_MAX_REGS (ISL29018_REG_ADD_DATA_MSB+1) #define ISL29018_REG_TEST 0x08 #define ISL29018_TEST_SHIFT 0 #define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) struct isl29018_chip { - struct i2c_client *client; + struct device *dev; + struct regmap *regmap; struct mutex lock; unsigned int lux_scale; unsigned int range; unsigned int adc_bit; int prox_scheme; - u8 reg_cache[ISL29018_MAX_REGS]; }; -static int isl29018_write_data(struct i2c_client *client, u8 reg, - u8 val, u8 mask, u8 shift) -{ - u8 regval = val; - int ret; - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); - - /* don't cache or mask REG_TEST */ - if (reg < ISL29018_MAX_REGS) { - regval = chip->reg_cache[reg]; - regval &= ~mask; - regval |= val << shift; - } - - ret = i2c_smbus_write_byte_data(client, reg, regval); - if (ret) { - dev_err(&client->dev, "Write to device fails status %x\n", ret); - } else { - /* don't update cache on err */ - if (reg < ISL29018_MAX_REGS) - chip->reg_cache[reg] = regval; - } - - return ret; -} - -static int isl29018_set_range(struct i2c_client *client, unsigned long range, +static int isl29018_set_range(struct isl29018_chip *chip, unsigned long range, unsigned int *new_range) { static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000}; @@ -109,11 +84,11 @@ static int isl29018_set_range(struct i2c_client *client, unsigned long range, if (i >= ARRAY_SIZE(supp_ranges)) return -EINVAL; - return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - i, COMMANDII_RANGE_MASK, COMMANDII_RANGE_SHIFT); + return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RANGE_MASK, i << COMMANDII_RANGE_SHIFT); } -static int isl29018_set_resolution(struct i2c_client *client, +static int isl29018_set_resolution(struct isl29018_chip *chip, unsigned long adcbit, unsigned int *conf_adc_bit) { static const unsigned long supp_adcbit[] = {16, 12, 8, 4}; @@ -129,48 +104,49 @@ static int isl29018_set_resolution(struct i2c_client *client, if (i >= ARRAY_SIZE(supp_adcbit)) return -EINVAL; - return isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - i, COMMANDII_RESOLUTION_MASK, - COMMANDII_RESOLUTION_SHIFT); + return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RESOLUTION_MASK, + i << COMMANDII_RESOLUTION_SHIFT); } -static int isl29018_read_sensor_input(struct i2c_client *client, int mode) +static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode) { int status; - int lsb; - int msb; + unsigned int lsb; + unsigned int msb; /* Set mode */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, - mode, COMMMAND1_OPMODE_MASK, COMMMAND1_OPMODE_SHIFT); + status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, + mode << COMMMAND1_OPMODE_SHIFT); if (status) { - dev_err(&client->dev, "Error in setting operating mode\n"); + dev_err(chip->dev, + "Error in setting operating mode err %d\n", status); return status; } msleep(CONVERSION_TIME_MS); - lsb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_LSB); - if (lsb < 0) { - dev_err(&client->dev, "Error in reading LSB DATA\n"); - return lsb; + status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_LSB, &lsb); + if (status < 0) { + dev_err(chip->dev, + "Error in reading LSB DATA with err %d\n", status); + return status; } - msb = i2c_smbus_read_byte_data(client, ISL29018_REG_ADD_DATA_MSB); - if (msb < 0) { - dev_err(&client->dev, "Error in reading MSB DATA\n"); - return msb; + status = regmap_read(chip->regmap, ISL29018_REG_ADD_DATA_MSB, &msb); + if (status < 0) { + dev_err(chip->dev, + "Error in reading MSB DATA with error %d\n", status); + return status; } - dev_vdbg(&client->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb); + dev_vdbg(chip->dev, "MSB 0x%x and LSB 0x%x\n", msb, lsb); return (msb << 8) | lsb; } -static int isl29018_read_lux(struct i2c_client *client, int *lux) +static int isl29018_read_lux(struct isl29018_chip *chip, int *lux) { int lux_data; - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); - lux_data = isl29018_read_sensor_input(client, - COMMMAND1_OPMODE_ALS_ONCE); + lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE); if (lux_data < 0) return lux_data; @@ -180,11 +156,11 @@ static int isl29018_read_lux(struct i2c_client *client, int *lux) return 0; } -static int isl29018_read_ir(struct i2c_client *client, int *ir) +static int isl29018_read_ir(struct isl29018_chip *chip, int *ir) { int ir_data; - ir_data = isl29018_read_sensor_input(client, COMMMAND1_OPMODE_IR_ONCE); + ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE); if (ir_data < 0) return ir_data; @@ -194,7 +170,7 @@ static int isl29018_read_ir(struct i2c_client *client, int *ir) return 0; } -static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, +static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme, int *near_ir) { int status; @@ -202,14 +178,15 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, int ir_data = -1; /* Do proximity sensing with required scheme */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMANDII, - scheme, COMMANDII_SCHEME_MASK, COMMANDII_SCHEME_SHIFT); + status = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_SCHEME_MASK, + scheme << COMMANDII_SCHEME_SHIFT); if (status) { - dev_err(&client->dev, "Error in setting operating mode\n"); + dev_err(chip->dev, "Error in setting operating mode\n"); return status; } - prox_data = isl29018_read_sensor_input(client, + prox_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_PROX_ONCE); if (prox_data < 0) return prox_data; @@ -219,8 +196,7 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, return 0; } - ir_data = isl29018_read_sensor_input(client, - COMMMAND1_OPMODE_IR_ONCE); + ir_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_IR_ONCE); if (ir_data < 0) return ir_data; @@ -238,7 +214,7 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, static ssize_t show_range(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%u\n", chip->range); @@ -247,9 +223,8 @@ static ssize_t show_range(struct device *dev, static ssize_t store_range(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; int status; unsigned long lval; unsigned int new_range; @@ -264,10 +239,11 @@ static ssize_t store_range(struct device *dev, } mutex_lock(&chip->lock); - status = isl29018_set_range(client, lval, &new_range); + status = isl29018_set_range(chip, lval, &new_range); if (status < 0) { mutex_unlock(&chip->lock); - dev_err(dev, "Error in setting max range\n"); + dev_err(dev, + "Error in setting max range with err %d\n", status); return status; } chip->range = new_range; @@ -280,7 +256,7 @@ static ssize_t store_range(struct device *dev, static ssize_t show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%u\n", chip->adc_bit); @@ -289,9 +265,8 @@ static ssize_t show_resolution(struct device *dev, static ssize_t store_resolution(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; int status; unsigned long lval; unsigned int new_adc_bit; @@ -304,7 +279,7 @@ static ssize_t store_resolution(struct device *dev, } mutex_lock(&chip->lock); - status = isl29018_set_resolution(client, lval, &new_adc_bit); + status = isl29018_set_resolution(chip, lval, &new_adc_bit); if (status < 0) { mutex_unlock(&chip->lock); dev_err(dev, "Error in setting resolution\n"); @@ -320,7 +295,7 @@ static ssize_t store_resolution(struct device *dev, static ssize_t show_prox_infrared_supression(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); /* return the "proximity scheme" i.e. if the chip does on chip @@ -331,7 +306,7 @@ static ssize_t show_prox_infrared_supression(struct device *dev, static ssize_t store_prox_infrared_supression(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); unsigned long lval; @@ -379,20 +354,20 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, { int ret = -EINVAL; struct isl29018_chip *chip = iio_priv(indio_dev); - struct i2c_client *client = chip->client; mutex_lock(&chip->lock); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: - ret = isl29018_read_lux(client, val); + ret = isl29018_read_lux(chip, val); break; case IIO_INTENSITY: - ret = isl29018_read_ir(client, val); + ret = isl29018_read_ir(chip, val); break; case IIO_PROXIMITY: - ret = isl29018_read_proximity_ir(client, + ret = isl29018_read_proximity_ir(chip, chip->prox_scheme, val); break; default: @@ -419,15 +394,17 @@ static const struct iio_chan_spec isl29018_channels[] = { .type = IIO_LIGHT, .indexed = 1, .channel = 0, - .processed_val = IIO_PROCESSED, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, }, { .type = IIO_INTENSITY, .modified = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, .channel2 = IIO_MOD_LIGHT_IR, }, { /* Unindexed in current ABI. But perhaps it should be. */ .type = IIO_PROXIMITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; @@ -456,15 +433,12 @@ static const struct attribute_group isl29108_group = { .attrs = isl29018_attributes, }; -static int isl29018_chip_init(struct i2c_client *client) +static int isl29018_chip_init(struct isl29018_chip *chip) { - struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); int status; int new_adc_bit; unsigned int new_range; - memset(chip->reg_cache, 0, sizeof(chip->reg_cache)); - /* Code added per Intersil Application Note 1534: * When VDD sinks to approximately 1.8V or below, some of * the part's registers may change their state. When VDD @@ -485,10 +459,9 @@ static int isl29018_chip_init(struct i2c_client *client) * the same thing EXCEPT the data sheet asks for a 1ms delay after * writing the CMD1 register. */ - status = isl29018_write_data(client, ISL29018_REG_TEST, 0, - ISL29018_TEST_MASK, ISL29018_TEST_SHIFT); + status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0); if (status < 0) { - dev_err(&client->dev, "Failed to clear isl29018 TEST reg." + dev_err(chip->dev, "Failed to clear isl29018 TEST reg." "(%d)\n", status); return status; } @@ -497,10 +470,9 @@ static int isl29018_chip_init(struct i2c_client *client) * "Operating Mode" (COMMAND1) register is reprogrammed when * data is read from the device. */ - status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0, - 0xff, 0); + status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0); if (status < 0) { - dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg." + dev_err(chip->dev, "Failed to clear isl29018 CMD1 reg." "(%d)\n", status); return status; } @@ -508,13 +480,13 @@ static int isl29018_chip_init(struct i2c_client *client) msleep(1); /* per data sheet, page 10 */ /* set defaults */ - status = isl29018_set_range(client, chip->range, &new_range); + status = isl29018_set_range(chip, chip->range, &new_range); if (status < 0) { - dev_err(&client->dev, "Init of isl29018 fails\n"); + dev_err(chip->dev, "Init of isl29018 fails\n"); return status; } - status = isl29018_set_resolution(client, chip->adc_bit, + status = isl29018_set_resolution(chip, chip->adc_bit, &new_adc_bit); return 0; @@ -527,6 +499,32 @@ static const struct iio_info isl29108_info = { .write_raw = &isl29018_write_raw, }; +static bool is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ISL29018_REG_ADD_DATA_LSB: + case ISL29018_REG_ADD_DATA_MSB: + case ISL29018_REG_ADD_COMMAND1: + case ISL29018_REG_TEST: + return true; + default: + return false; + } +} + +/* + * isl29018_regmap_config: regmap configuration. + * Use RBTREE mechanism for caching. + */ +static const struct regmap_config isl29018_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_reg = is_volatile_reg, + .max_register = ISL29018_REG_TEST, + .num_reg_defaults_raw = ISL29018_REG_TEST + 1, + .cache_type = REGCACHE_RBTREE, +}; + static int __devinit isl29018_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -534,7 +532,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, struct iio_dev *indio_dev; int err; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { dev_err(&client->dev, "iio allocation fails\n"); err = -ENOMEM; @@ -543,7 +541,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, chip = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); - chip->client = client; + chip->dev = &client->dev; mutex_init(&chip->lock); @@ -551,7 +549,14 @@ static int __devinit isl29018_probe(struct i2c_client *client, chip->range = 1000; chip->adc_bit = 16; - err = isl29018_chip_init(client); + chip->regmap = devm_regmap_init_i2c(client, &isl29018_regmap_config); + if (IS_ERR(chip->regmap)) { + err = PTR_ERR(chip->regmap); + dev_err(chip->dev, "regmap initialization failed: %d\n", err); + goto exit; + } + + err = isl29018_chip_init(chip); if (err) goto exit_iio_free; @@ -569,7 +574,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, return 0; exit_iio_free: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } @@ -580,7 +585,7 @@ static int __devexit isl29018_remove(struct i2c_client *client) dev_dbg(&client->dev, "%s()\n", __func__); iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } @@ -593,7 +598,7 @@ static const struct i2c_device_id isl29018_id[] = { MODULE_DEVICE_TABLE(i2c, isl29018_id); static const struct of_device_id isl29018_of_match[] = { - { .compatible = "invn,isl29018", }, + { .compatible = "isil,isl29018", }, { }, }; MODULE_DEVICE_TABLE(of, isl29018_of_match); diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c new file mode 100644 index 0000000..33a4c3f --- /dev/null +++ b/drivers/staging/iio/light/isl29028.c @@ -0,0 +1,566 @@ +/* + * IIO driver for the light sensor ISL29028. + * ISL29028 is Concurrent Ambient Light and Proximity Sensor + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/regmap.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> + +#define CONVERSION_TIME_MS 100 + +#define ISL29028_REG_CONFIGURE 0x01 + +#define CONFIGURE_ALS_IR_MODE_ALS 0 +#define CONFIGURE_ALS_IR_MODE_IR BIT(0) +#define CONFIGURE_ALS_IR_MODE_MASK BIT(0) + +#define CONFIGURE_ALS_RANGE_LOW_LUX 0 +#define CONFIGURE_ALS_RANGE_HIGH_LUX BIT(1) +#define CONFIGURE_ALS_RANGE_MASK BIT(1) + +#define CONFIGURE_ALS_DIS 0 +#define CONFIGURE_ALS_EN BIT(2) +#define CONFIGURE_ALS_EN_MASK BIT(2) + +#define CONFIGURE_PROX_DRIVE BIT(3) + +#define CONFIGURE_PROX_SLP_SH 4 +#define CONFIGURE_PROX_SLP_MASK (7 << CONFIGURE_PROX_SLP_SH) + +#define CONFIGURE_PROX_EN BIT(7) +#define CONFIGURE_PROX_EN_MASK BIT(7) + +#define ISL29028_REG_INTERRUPT 0x02 + +#define ISL29028_REG_PROX_DATA 0x08 +#define ISL29028_REG_ALSIR_L 0x09 +#define ISL29028_REG_ALSIR_U 0x0A + +#define ISL29028_REG_TEST1_MODE 0x0E +#define ISL29028_REG_TEST2_MODE 0x0F + +#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1) + +enum als_ir_mode { + MODE_NONE = 0, + MODE_ALS, + MODE_IR +}; + +struct isl29028_chip { + struct device *dev; + struct mutex lock; + struct regmap *regmap; + + unsigned int prox_sampling; + bool enable_prox; + + int lux_scale; + int als_ir_mode; +}; + +static int isl29028_set_proxim_sampling(struct isl29028_chip *chip, + unsigned int sampling) +{ + static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0}; + int sel; + unsigned int period = DIV_ROUND_UP(1000, sampling); + + for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) { + if (period >= prox_period[sel]) + break; + } + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_PROX_SLP_MASK, sel << CONFIGURE_PROX_SLP_SH); +} + +static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable) +{ + int ret; + int val = 0; + + if (enable) + val = CONFIGURE_PROX_EN; + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_PROX_EN_MASK, val); + if (ret < 0) + return ret; + + /* Wait for conversion to be complete for first sample */ + mdelay(DIV_ROUND_UP(1000, chip->prox_sampling)); + return 0; +} + +static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale) +{ + int val = (lux_scale == 2000) ? CONFIGURE_ALS_RANGE_HIGH_LUX : + CONFIGURE_ALS_RANGE_LOW_LUX; + + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_RANGE_MASK, val); +} + +static int isl29028_set_als_ir_mode(struct isl29028_chip *chip, + enum als_ir_mode mode) +{ + int ret = 0; + + switch (mode) { + case MODE_ALS: + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_ALS); + if (ret < 0) + return ret; + + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_RANGE_MASK, CONFIGURE_ALS_RANGE_HIGH_LUX); + break; + + case MODE_IR: + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_IR_MODE_MASK, CONFIGURE_ALS_IR_MODE_IR); + break; + + case MODE_NONE: + return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_DIS); + } + + if (ret < 0) + return ret; + + /* Enable the ALS/IR */ + ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE, + CONFIGURE_ALS_EN_MASK, CONFIGURE_ALS_EN); + if (ret < 0) + return ret; + + /* Need to wait for conversion time if ALS/IR mode enabled */ + mdelay(CONVERSION_TIME_MS); + return 0; +} + +static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir) +{ + unsigned int lsb; + unsigned int msb; + int ret; + + ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb); + if (ret < 0) { + dev_err(chip->dev, + "Error in reading register ALSIR_L err %d\n", ret); + return ret; + } + + ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb); + if (ret < 0) { + dev_err(chip->dev, + "Error in reading register ALSIR_U err %d\n", ret); + return ret; + } + + *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF); + return 0; +} + +static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox) +{ + unsigned int data; + int ret; + + ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data); + if (ret < 0) { + dev_err(chip->dev, "Error in reading register %d, error %d\n", + ISL29028_REG_PROX_DATA, ret); + return ret; + } + *prox = data; + return 0; +} + +static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data) +{ + int ret; + + if (!chip->enable_prox) { + ret = isl29028_enable_proximity(chip, true); + if (ret < 0) + return ret; + chip->enable_prox = true; + } + return isl29028_read_proxim(chip, prox_data); +} + +static int isl29028_als_get(struct isl29028_chip *chip, int *als_data) +{ + int ret; + int als_ir_data; + + if (chip->als_ir_mode != MODE_ALS) { + ret = isl29028_set_als_ir_mode(chip, MODE_ALS); + if (ret < 0) { + dev_err(chip->dev, + "Error in enabling ALS mode err %d\n", ret); + return ret; + } + chip->als_ir_mode = MODE_ALS; + } + + ret = isl29028_read_als_ir(chip, &als_ir_data); + if (ret < 0) + return ret; + + /* + * convert als data count to lux. + * if lux_scale = 125, lux = count * 0.031 + * if lux_scale = 2000, lux = count * 0.49 + */ + if (chip->lux_scale == 125) + als_ir_data = (als_ir_data * 31) / 1000; + else + als_ir_data = (als_ir_data * 49) / 100; + + *als_data = als_ir_data; + return 0; +} + +static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data) +{ + int ret; + + if (chip->als_ir_mode != MODE_IR) { + ret = isl29028_set_als_ir_mode(chip, MODE_IR); + if (ret < 0) { + dev_err(chip->dev, + "Error in enabling IR mode err %d\n", ret); + return ret; + } + chip->als_ir_mode = MODE_IR; + } + return isl29028_read_als_ir(chip, ir_data); +} + +/* Channel IO */ +static int isl29028_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) +{ + struct isl29028_chip *chip = iio_priv(indio_dev); + int ret = -EINVAL; + + mutex_lock(&chip->lock); + switch (chan->type) { + case IIO_PROXIMITY: + if (mask != IIO_CHAN_INFO_SAMP_FREQ) { + dev_err(chip->dev, + "proximity: mask value 0x%08lx not supported\n", + mask); + break; + } + if (val < 1 || val > 100) { + dev_err(chip->dev, + "Samp_freq %d is not in range[1:100]\n", val); + break; + } + ret = isl29028_set_proxim_sampling(chip, val); + if (ret < 0) { + dev_err(chip->dev, + "Setting proximity samp_freq fail, err %d\n", + ret); + break; + } + chip->prox_sampling = val; + break; + + case IIO_LIGHT: + if (mask != IIO_CHAN_INFO_SCALE) { + dev_err(chip->dev, + "light: mask value 0x%08lx not supported\n", + mask); + break; + } + if ((val != 125) && (val != 2000)) { + dev_err(chip->dev, + "lux scale %d is invalid [125, 2000]\n", val); + break; + } + ret = isl29028_set_als_scale(chip, val); + if (ret < 0) { + dev_err(chip->dev, + "Setting lux scale fail with error %d\n", ret); + break; + } + chip->lux_scale = val; + break; + + default: + dev_err(chip->dev, "Unsupported channel type\n"); + break; + } + mutex_unlock(&chip->lock); + return ret; +} + +static int isl29028_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) +{ + struct isl29028_chip *chip = iio_priv(indio_dev); + int ret = -EINVAL; + + mutex_lock(&chip->lock); + switch (mask) { + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_LIGHT: + ret = isl29028_als_get(chip, val); + break; + case IIO_INTENSITY: + ret = isl29028_ir_get(chip, val); + break; + case IIO_PROXIMITY: + ret = isl29028_proxim_get(chip, val); + break; + default: + break; + } + if (ret < 0) + break; + ret = IIO_VAL_INT; + break; + + case IIO_CHAN_INFO_SAMP_FREQ: + if (chan->type != IIO_PROXIMITY) + break; + *val = chip->prox_sampling; + ret = IIO_VAL_INT; + break; + + case IIO_CHAN_INFO_SCALE: + if (chan->type != IIO_LIGHT) + break; + *val = chip->lux_scale; + ret = IIO_VAL_INT; + break; + + default: + dev_err(chip->dev, "mask value 0x%08lx not supported\n", mask); + break; + } + mutex_unlock(&chip->lock); + return ret; +} + +static IIO_CONST_ATTR(in_proximity_sampling_frequency_available, + "1, 3, 5, 10, 13, 20, 83, 100"); +static IIO_CONST_ATTR(in_illuminance_scale_available, "125, 2000"); + +#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) +#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) +static struct attribute *isl29028_attributes[] = { + ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available), + ISL29028_CONST_ATTR(in_illuminance_scale_available), + NULL, +}; + +static const struct attribute_group isl29108_group = { + .attrs = isl29028_attributes, +}; + +static const struct iio_chan_spec isl29028_channels[] = { + { + .type = IIO_LIGHT, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SAMP_FREQ_SEPARATE_BIT, + } +}; + +static const struct iio_info isl29028_info = { + .attrs = &isl29108_group, + .driver_module = THIS_MODULE, + .read_raw = &isl29028_read_raw, + .write_raw = &isl29028_write_raw, +}; + +static int isl29028_chip_init(struct isl29028_chip *chip) +{ + int ret; + + chip->enable_prox = false; + chip->prox_sampling = 20; + chip->lux_scale = 2000; + chip->als_ir_mode = MODE_NONE; + + ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_TEST1_MODE, ret); + return ret; + } + ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_TEST2_MODE, ret); + return ret; + } + + ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0); + if (ret < 0) { + dev_err(chip->dev, "%s(): write to reg %d failed, err = %d\n", + __func__, ISL29028_REG_CONFIGURE, ret); + return ret; + } + + ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling); + if (ret < 0) { + dev_err(chip->dev, "%s(): setting the proximity, err = %d\n", + __func__, ret); + return ret; + } + + ret = isl29028_set_als_scale(chip, chip->lux_scale); + if (ret < 0) + dev_err(chip->dev, "%s(): setting als scale failed, err = %d\n", + __func__, ret); + return ret; +} + +static bool is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case ISL29028_REG_INTERRUPT: + case ISL29028_REG_PROX_DATA: + case ISL29028_REG_ALSIR_L: + case ISL29028_REG_ALSIR_U: + return true; + default: + return false; + } +} + +static const struct regmap_config isl29028_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_reg = is_volatile_reg, + .max_register = ISL29028_NUM_REGS - 1, + .num_reg_defaults_raw = ISL29028_NUM_REGS, + .cache_type = REGCACHE_RBTREE, +}; + +static int __devinit isl29028_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct isl29028_chip *chip; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_device_alloc(sizeof(*chip)); + if (!indio_dev) { + dev_err(&client->dev, "iio allocation fails\n"); + return -ENOMEM; + } + + chip = iio_priv(indio_dev); + + i2c_set_clientdata(client, indio_dev); + chip->dev = &client->dev; + mutex_init(&chip->lock); + + chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config); + if (IS_ERR(chip->regmap)) { + ret = PTR_ERR(chip->regmap); + dev_err(chip->dev, "regmap initialization failed: %d\n", ret); + goto exit_iio_free; + } + + ret = isl29028_chip_init(chip); + if (ret < 0) { + dev_err(chip->dev, "chip initialization failed: %d\n", ret); + goto exit_iio_free; + } + + indio_dev->info = &isl29028_info; + indio_dev->channels = isl29028_channels; + indio_dev->num_channels = ARRAY_SIZE(isl29028_channels); + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(chip->dev, "iio registration fails with error %d\n", + ret); + goto exit_iio_free; + } + return 0; + +exit_iio_free: + iio_device_free(indio_dev); + return ret; +} + +static int __devexit isl29028_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_device_free(indio_dev); + return 0; +} + +static const struct i2c_device_id isl29028_id[] = { + {"isl29028", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, isl29028_id); + +static const struct of_device_id isl29028_of_match[] = { + { .compatible = "isil,isl29028", }, + { }, +}; +MODULE_DEVICE_TABLE(of, isl29028_of_match); + +static struct i2c_driver isl29028_driver = { + .class = I2C_CLASS_HWMON, + .driver = { + .name = "isl29028", + .owner = THIS_MODULE, + .of_match_table = isl29028_of_match, + }, + .probe = isl29028_probe, + .remove = __devexit_p(isl29028_remove), + .id_table = isl29028_id, +}; + +module_i2c_driver(isl29028_driver); + +MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 546c95a..9d740be 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -35,9 +35,9 @@ #include <linux/err.h> #include <linux/slab.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../events.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/events.h> #include "tsl2563.h" /* Use this many bits for fraction part. */ @@ -465,7 +465,7 @@ static int tsl2563_write_raw(struct iio_dev *indio_dev, { struct tsl2563_chip *chip = iio_priv(indio_dev); - if (chan->channel == 0) + if (chan->channel == IIO_MOD_LIGHT_BOTH) chip->calib0 = calib_from_sysfs(val); else chip->calib1 = calib_from_sysfs(val); @@ -485,7 +485,8 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, mutex_lock(&chip->lock); switch (m) { - case 0: + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: switch (chan->type) { case IIO_LIGHT: ret = tsl2563_get_adc(chip); @@ -534,12 +535,14 @@ static const struct iio_chan_spec tsl2563_channels[] = { { .type = IIO_LIGHT, .indexed = 1, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, .channel = 0, }, { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_BOTH, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | IIO_EV_BIT(IIO_EV_TYPE_THRESH, @@ -548,7 +551,8 @@ static const struct iio_chan_spec tsl2563_channels[] = { .type = IIO_INTENSITY, .modified = 1, .channel2 = IIO_MOD_LIGHT_IR, - .info_mask = IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, } }; @@ -710,7 +714,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, int err = 0; u8 id = 0; - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (!indio_dev) return -ENOMEM; @@ -797,7 +801,7 @@ fail2: if (client->irq) free_irq(client->irq, indio_dev); fail1: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return err; } @@ -818,7 +822,7 @@ static int tsl2563_remove(struct i2c_client *client) if (client->irq) free_irq(client->irq, indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 8671d98..5e23ad5 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -28,7 +28,7 @@ #include <linux/unistd.h> #include <linux/slab.h> #include <linux/module.h> -#include "../iio.h" +#include <linux/iio/iio.h> #define TSL258X_MAX_DEVICE_REGS 32 @@ -483,7 +483,7 @@ static int taos_chip_off(struct iio_dev *indio_dev) static ssize_t taos_power_state_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_chip_status); @@ -492,7 +492,7 @@ static ssize_t taos_power_state_show(struct device *dev, static ssize_t taos_power_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -509,7 +509,7 @@ static ssize_t taos_power_state_store(struct device *dev, static ssize_t taos_gain_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); char gain[4] = {0}; @@ -534,7 +534,7 @@ static ssize_t taos_gain_show(struct device *dev, static ssize_t taos_gain_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; @@ -571,7 +571,7 @@ static ssize_t taos_gain_available_show(struct device *dev, static ssize_t taos_als_time_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_time); @@ -580,7 +580,7 @@ static ssize_t taos_als_time_show(struct device *dev, static ssize_t taos_als_time_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; @@ -608,7 +608,7 @@ static ssize_t taos_als_time_available_show(struct device *dev, static ssize_t taos_als_trim_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_gain_trim); @@ -617,7 +617,7 @@ static ssize_t taos_als_trim_show(struct device *dev, static ssize_t taos_als_trim_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; @@ -633,7 +633,7 @@ static ssize_t taos_als_trim_store(struct device *dev, static ssize_t taos_als_cal_target_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_cal_target); @@ -642,7 +642,7 @@ static ssize_t taos_als_cal_target_show(struct device *dev, static ssize_t taos_als_cal_target_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; @@ -660,7 +660,7 @@ static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr, { int ret; - ret = taos_get_lux(dev_get_drvdata(dev)); + ret = taos_get_lux(dev_to_iio_dev(dev)); if (ret < 0) return ret; @@ -670,7 +670,7 @@ static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr, static ssize_t taos_do_calibrate(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -708,7 +708,7 @@ static ssize_t taos_luxtable_show(struct device *dev, static ssize_t taos_luxtable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct tsl2583_chip *chip = iio_priv(indio_dev); int value[ARRAY_SIZE(taos_device_lux)*3 + 1]; int n; @@ -815,7 +815,7 @@ static int __devinit taos_probe(struct i2c_client *clientp, return -EOPNOTSUPP; } - indio_dev = iio_allocate_device(sizeof(*chip)); + indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { ret = -ENOMEM; dev_err(&clientp->dev, "iio allocation failed\n"); @@ -879,7 +879,7 @@ static int __devinit taos_probe(struct i2c_client *clientp, dev_info(&clientp->dev, "Light sensor found.\n"); return 0; fail1: - iio_free_device(indio_dev); + iio_device_free(indio_dev); fail2: return ret; } @@ -926,7 +926,7 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume); static int __devexit taos_remove(struct i2c_client *client) { iio_device_unregister(i2c_get_clientdata(client)); - iio_free_device(i2c_get_clientdata(client)); + iio_device_free(i2c_get_clientdata(client)); return 0; } diff --git a/drivers/staging/iio/light/tsl2x7x.h b/drivers/staging/iio/light/tsl2x7x.h new file mode 100755 index 0000000..c4acf5f --- /dev/null +++ b/drivers/staging/iio/light/tsl2x7x.h @@ -0,0 +1,100 @@ +/* + * Device driver for monitoring ambient light intensity (lux) + * and proximity (prox) within the TAOS TSL2X7X family of devices. + * + * Copyright (c) 2012, TAOS Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __TSL2X7X_H +#define __TSL2X7X_H +#include <linux/pm.h> + +/* Max number of segments allowable in LUX table */ +#define TSL2X7X_MAX_LUX_TABLE_SIZE 9 +#define MAX_DEFAULT_TABLE_BYTES (sizeof(int) * TSL2X7X_MAX_LUX_TABLE_SIZE) + +struct iio_dev; + +struct tsl2x7x_lux { + unsigned int ratio; + unsigned int ch0; + unsigned int ch1; +}; + +/** + * struct tsl2x7x_default_settings - power on defaults unless + * overridden by platform data. + * @als_time: ALS Integration time - multiple of 50mS + * @als_gain: Index into the ALS gain table. + * @als_gain_trim: default gain trim to account for + * aperture effects. + * @wait_time: Time between PRX and ALS cycles + * in 2.7 periods + * @prx_time: 5.2ms prox integration time - + * decrease in 2.7ms periods + * @prx_gain: Proximity gain index + * @prox_config: Prox configuration filters. + * @als_cal_target: Known external ALS reading for + * calibration. + * @interrupts_en: Enable/Disable - 0x00 = none, 0x10 = als, + * 0x20 = prx, 0x30 = bth + * @persistence: H/W Filters, Number of 'out of limits' + * ADC readings PRX/ALS. + * @als_thresh_low: CH0 'low' count to trigger interrupt. + * @als_thresh_high: CH0 'high' count to trigger interrupt. + * @prox_thres_low: Low threshold proximity detection. + * @prox_thres_high: High threshold proximity detection + * @prox_pulse_count: Number if proximity emitter pulses + * @prox_max_samples_cal: Used for prox cal. + */ +struct tsl2x7x_settings { + int als_time; + int als_gain; + int als_gain_trim; + int wait_time; + int prx_time; + int prox_gain; + int prox_config; + int als_cal_target; + u8 interrupts_en; + u8 persistence; + int als_thresh_low; + int als_thresh_high; + int prox_thres_low; + int prox_thres_high; + int prox_pulse_count; + int prox_max_samples_cal; +}; + +/** + * struct tsl2X7X_platform_data - Platform callback, glass and defaults + * @platform_power: Suspend/resume platform callback + * @power_on: Power on callback + * @power_off: Power off callback + * @platform_lux_table: Device specific glass coefficents + * @platform_default_settings: Device specific power on defaults + * + */ +struct tsl2X7X_platform_data { + int (*platform_power)(struct device *dev, pm_message_t); + int (*power_on) (struct iio_dev *indio_dev); + int (*power_off) (struct i2c_client *dev); + struct tsl2x7x_lux platform_lux_table[TSL2X7X_MAX_LUX_TABLE_SIZE]; + struct tsl2x7x_settings *platform_default_settings; +}; + +#endif /* __TSL2X7X_H */ diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c new file mode 100755 index 0000000..c3b05a1 --- /dev/null +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -0,0 +1,2082 @@ +/* + * Device driver for monitoring ambient light intensity in (lux) + * and proximity detection (prox) within the TAOS TSL2X7X family of devices. + * + * Copyright (c) 2012, TAOS Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/errno.h> +#include <linux/delay.h> +#include <linux/mutex.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/iio/events.h> +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include "tsl2x7x.h" + +/* Cal defs*/ +#define PROX_STAT_CAL 0 +#define PROX_STAT_SAMP 1 +#define MAX_SAMPLES_CAL 200 + +/* TSL2X7X Device ID */ +#define TRITON_ID 0x00 +#define SWORDFISH_ID 0x30 +#define HALIBUT_ID 0x20 + +/* Lux calculation constants */ +#define TSL2X7X_LUX_CALC_OVER_FLOW 65535 + +/* TAOS Register definitions - note: + * depending on device, some of these register are not used and the + * register address is benign. + */ +/* 2X7X register offsets */ +#define TSL2X7X_MAX_CONFIG_REG 16 + +/* Device Registers and Masks */ +#define TSL2X7X_CNTRL 0x00 +#define TSL2X7X_ALS_TIME 0X01 +#define TSL2X7X_PRX_TIME 0x02 +#define TSL2X7X_WAIT_TIME 0x03 +#define TSL2X7X_ALS_MINTHRESHLO 0X04 +#define TSL2X7X_ALS_MINTHRESHHI 0X05 +#define TSL2X7X_ALS_MAXTHRESHLO 0X06 +#define TSL2X7X_ALS_MAXTHRESHHI 0X07 +#define TSL2X7X_PRX_MINTHRESHLO 0X08 +#define TSL2X7X_PRX_MINTHRESHHI 0X09 +#define TSL2X7X_PRX_MAXTHRESHLO 0X0A +#define TSL2X7X_PRX_MAXTHRESHHI 0X0B +#define TSL2X7X_PERSISTENCE 0x0C +#define TSL2X7X_PRX_CONFIG 0x0D +#define TSL2X7X_PRX_COUNT 0x0E +#define TSL2X7X_GAIN 0x0F +#define TSL2X7X_NOTUSED 0x10 +#define TSL2X7X_REVID 0x11 +#define TSL2X7X_CHIPID 0x12 +#define TSL2X7X_STATUS 0x13 +#define TSL2X7X_ALS_CHAN0LO 0x14 +#define TSL2X7X_ALS_CHAN0HI 0x15 +#define TSL2X7X_ALS_CHAN1LO 0x16 +#define TSL2X7X_ALS_CHAN1HI 0x17 +#define TSL2X7X_PRX_LO 0x18 +#define TSL2X7X_PRX_HI 0x19 + +/* tsl2X7X cmd reg masks */ +#define TSL2X7X_CMD_REG 0x80 +#define TSL2X7X_CMD_SPL_FN 0x60 + +#define TSL2X7X_CMD_PROX_INT_CLR 0X05 +#define TSL2X7X_CMD_ALS_INT_CLR 0x06 +#define TSL2X7X_CMD_PROXALS_INT_CLR 0X07 + +/* tsl2X7X cntrl reg masks */ +#define TSL2X7X_CNTL_ADC_ENBL 0x02 +#define TSL2X7X_CNTL_PWR_ON 0x01 + +/* tsl2X7X status reg masks */ +#define TSL2X7X_STA_ADC_VALID 0x01 +#define TSL2X7X_STA_PRX_VALID 0x02 +#define TSL2X7X_STA_ADC_PRX_VALID (TSL2X7X_STA_ADC_VALID |\ + TSL2X7X_STA_PRX_VALID) +#define TSL2X7X_STA_ALS_INTR 0x10 +#define TSL2X7X_STA_PRX_INTR 0x20 + +/* tsl2X7X cntrl reg masks */ +#define TSL2X7X_CNTL_REG_CLEAR 0x00 +#define TSL2X7X_CNTL_PROX_INT_ENBL 0X20 +#define TSL2X7X_CNTL_ALS_INT_ENBL 0X10 +#define TSL2X7X_CNTL_WAIT_TMR_ENBL 0X08 +#define TSL2X7X_CNTL_PROX_DET_ENBL 0X04 +#define TSL2X7X_CNTL_PWRON 0x01 +#define TSL2X7X_CNTL_ALSPON_ENBL 0x03 +#define TSL2X7X_CNTL_INTALSPON_ENBL 0x13 +#define TSL2X7X_CNTL_PROXPON_ENBL 0x0F +#define TSL2X7X_CNTL_INTPROXPON_ENBL 0x2F + +/*Prox diode to use */ +#define TSL2X7X_DIODE0 0x10 +#define TSL2X7X_DIODE1 0x20 +#define TSL2X7X_DIODE_BOTH 0x30 + +/* LED Power */ +#define TSL2X7X_mA100 0x00 +#define TSL2X7X_mA50 0x40 +#define TSL2X7X_mA25 0x80 +#define TSL2X7X_mA13 0xD0 +#define TSL2X7X_MAX_TIMER_CNT (0xFF) + +/*Common device IIO EventMask */ +#define TSL2X7X_EVENT_MASK \ + (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ + IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)), + +#define TSL2X7X_MIN_ITIME 3 + +/* TAOS txx2x7x Device family members */ +enum { + tsl2571, + tsl2671, + tmd2671, + tsl2771, + tmd2771, + tsl2572, + tsl2672, + tmd2672, + tsl2772, + tmd2772 +}; + +enum { + TSL2X7X_CHIP_UNKNOWN = 0, + TSL2X7X_CHIP_WORKING = 1, + TSL2X7X_CHIP_SUSPENDED = 2 +}; + +struct tsl2x7x_parse_result { + int integer; + int fract; +}; + +/* Per-device data */ +struct tsl2x7x_als_info { + u16 als_ch0; + u16 als_ch1; + u16 lux; +}; + +struct tsl2x7x_prox_stat { + int min; + int max; + int mean; + unsigned long stddev; +}; + +struct tsl2x7x_chip_info { + int chan_table_elements; + struct iio_chan_spec channel[4]; + const struct iio_info *info; +}; + +struct tsl2X7X_chip { + kernel_ulong_t id; + struct mutex prox_mutex; + struct mutex als_mutex; + struct i2c_client *client; + u16 prox_data; + struct tsl2x7x_als_info als_cur_info; + struct tsl2x7x_settings tsl2x7x_settings; + struct tsl2X7X_platform_data *pdata; + int als_time_scale; + int als_saturation; + int tsl2x7x_chip_status; + u8 tsl2x7x_config[TSL2X7X_MAX_CONFIG_REG]; + const struct tsl2x7x_chip_info *chip_info; + const struct iio_info *info; + s64 event_timestamp; + /* This structure is intentionally large to accommodate + * updates via sysfs. */ + /* Sized to 9 = max 8 segments + 1 termination segment */ + struct tsl2x7x_lux tsl2x7x_device_lux[TSL2X7X_MAX_LUX_TABLE_SIZE]; +}; + +/* Different devices require different coefficents */ +static const struct tsl2x7x_lux tsl2x71_lux_table[] = { + { 14461, 611, 1211 }, + { 18540, 352, 623 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tmd2x71_lux_table[] = { + { 11635, 115, 256 }, + { 15536, 87, 179 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tsl2x72_lux_table[] = { + { 14013, 466, 917 }, + { 18222, 310, 552 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux tmd2x72_lux_table[] = { + { 13218, 130, 262 }, + { 17592, 92, 169 }, + { 0, 0, 0 }, +}; + +static const struct tsl2x7x_lux *tsl2x7x_default_lux_table_group[] = { + [tsl2571] = tsl2x71_lux_table, + [tsl2671] = tsl2x71_lux_table, + [tmd2671] = tmd2x71_lux_table, + [tsl2771] = tsl2x71_lux_table, + [tmd2771] = tmd2x71_lux_table, + [tsl2572] = tsl2x72_lux_table, + [tsl2672] = tsl2x72_lux_table, + [tmd2672] = tmd2x72_lux_table, + [tsl2772] = tsl2x72_lux_table, + [tmd2772] = tmd2x72_lux_table, +}; + +static const struct tsl2x7x_settings tsl2x7x_default_settings = { + .als_time = 219, /* 101 ms */ + .als_gain = 0, + .prx_time = 254, /* 5.4 ms */ + .prox_gain = 1, + .wait_time = 245, + .prox_config = 0, + .als_gain_trim = 1000, + .als_cal_target = 150, + .als_thresh_low = 200, + .als_thresh_high = 256, + .persistence = 255, + .interrupts_en = 0, + .prox_thres_low = 0, + .prox_thres_high = 512, + .prox_max_samples_cal = 30, + .prox_pulse_count = 8 +}; + +static const s16 tsl2X7X_als_gainadj[] = { + 1, + 8, + 16, + 120 +}; + +static const s16 tsl2X7X_prx_gainadj[] = { + 1, + 2, + 4, + 8 +}; + +/* Channel variations */ +enum { + ALS, + PRX, + ALSPRX, + PRX2, + ALSPRX2, +}; + +static const u8 device_channel_config[] = { + ALS, + PRX, + PRX, + ALSPRX, + ALSPRX, + ALS, + PRX2, + PRX2, + ALSPRX2, + ALSPRX2 +}; + +/** + * tsl2x7x_parse_buffer() - parse a decimal result from a buffer. + * @*buf: pointer to char buffer to parse + * @*result: pointer to buffer to contain + * resulting interger / decimal as ints. + * + */ +static int +tsl2x7x_parse_buffer(const char *buf, struct tsl2x7x_parse_result *result) +{ + int integer = 0, fract = 0, fract_mult = 100000; + bool integer_part = true, negative = false; + + if (buf[0] == '-') { + negative = true; + buf++; + } + + while (*buf) { + if ('0' <= *buf && *buf <= '9') { + if (integer_part) + integer = integer*10 + *buf - '0'; + else { + fract += fract_mult*(*buf - '0'); + if (fract_mult == 1) + break; + fract_mult /= 10; + } + } else if (*buf == '\n') { + if (*(buf + 1) == '\0') + break; + else + return -EINVAL; + } else if (*buf == '.') { + integer_part = false; + } else { + return -EINVAL; + } + buf++; + } + if (negative) { + if (integer) + integer = -integer; + else + fract = -fract; + } + + result->integer = integer; + result->fract = fract; + + return 0; +} + +/** + * tsl2x7x_i2c_read() - Read a byte from a register. + * @client: i2c client + * @reg: device register to read from + * @*val: pointer to location to store register contents. + * + */ +static int +tsl2x7x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) +{ + int ret = 0; + + /* select register to write */ + ret = i2c_smbus_write_byte(client, (TSL2X7X_CMD_REG | reg)); + if (ret < 0) { + dev_err(&client->dev, "%s: failed to write register %x\n" + , __func__, reg); + return ret; + } + + /* read the data */ + ret = i2c_smbus_read_byte(client); + if (ret >= 0) + *val = (u8)ret; + else + dev_err(&client->dev, "%s: failed to read register %x\n" + , __func__, reg); + + return ret; +} + +/** + * tsl2x7x_get_lux() - Reads and calculates current lux value. + * @indio_dev: pointer to IIO device + * + * The raw ch0 and ch1 values of the ambient light sensed in the last + * integration cycle are read from the device. + * Time scale factor array values are adjusted based on the integration time. + * The raw values are multiplied by a scale factor, and device gain is obtained + * using gain index. Limit checks are done next, then the ratio of a multiple + * of ch1 value, to the ch0 value, is calculated. Array tsl2x7x_device_lux[] + * is then scanned to find the first ratio value that is just above the ratio + * we just calculated. The ch0 and ch1 multiplier constants in the array are + * then used along with the time scale factor array values, to calculate the + * lux. + */ +static int tsl2x7x_get_lux(struct iio_dev *indio_dev) +{ + u16 ch0, ch1; /* separated ch0/ch1 data from device */ + u32 lux; /* raw lux calculated from device data */ + u64 lux64; + u32 ratio; + u8 buf[4]; + struct tsl2x7x_lux *p; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int i, ret; + u32 ch0lux = 0; + u32 ch1lux = 0; + + if (mutex_trylock(&chip->als_mutex) == 0) + return chip->als_cur_info.lux; /* busy, so return LAST VALUE */ + + if (chip->tsl2x7x_chip_status != TSL2X7X_CHIP_WORKING) { + /* device is not enabled */ + dev_err(&chip->client->dev, "%s: device is not enabled\n", + __func__); + ret = -EBUSY ; + goto out_unlock; + } + + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &buf[0]); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: Failed to read STATUS Reg\n", __func__); + goto out_unlock; + } + /* is data new & valid */ + if (!(buf[0] & TSL2X7X_STA_ADC_VALID)) { + dev_err(&chip->client->dev, + "%s: data not valid yet\n", __func__); + ret = chip->als_cur_info.lux; /* return LAST VALUE */ + goto out_unlock; + } + + for (i = 0; i < 4; i++) { + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | (TSL2X7X_ALS_CHAN0LO + i)), + &buf[i]); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to read. err=%x\n", __func__, ret); + goto out_unlock; + } + } + + /* clear any existing interrupt status */ + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | + TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_ALS_INT_CLR)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: i2c_write_command failed - err = %d\n", + __func__, ret); + goto out_unlock; /* have no data, so return failure */ + } + + /* extract ALS/lux data */ + ch0 = le16_to_cpup((const __le16 *)&buf[0]); + ch1 = le16_to_cpup((const __le16 *)&buf[2]); + + chip->als_cur_info.als_ch0 = ch0; + chip->als_cur_info.als_ch1 = ch1; + + if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) { + lux = TSL2X7X_LUX_CALC_OVER_FLOW; + goto return_max; + } + + if (ch0 == 0) { + /* have no data, so return LAST VALUE */ + ret = chip->als_cur_info.lux; + goto out_unlock; + } + /* calculate ratio */ + ratio = (ch1 << 15) / ch0; + /* convert to unscaled lux using the pointer to the table */ + p = (struct tsl2x7x_lux *) chip->tsl2x7x_device_lux; + while (p->ratio != 0 && p->ratio < ratio) + p++; + + if (p->ratio == 0) { + lux = 0; + } else { + ch0lux = DIV_ROUND_UP((ch0 * p->ch0), + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); + ch1lux = DIV_ROUND_UP((ch1 * p->ch1), + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); + lux = ch0lux - ch1lux; + } + + /* note: lux is 31 bit max at this point */ + if (ch1lux > ch0lux) { + dev_dbg(&chip->client->dev, "ch1lux > ch0lux-return last value\n"); + ret = chip->als_cur_info.lux; + goto out_unlock; + } + + /* adjust for active time scale */ + if (chip->als_time_scale == 0) + lux = 0; + else + lux = (lux + (chip->als_time_scale >> 1)) / + chip->als_time_scale; + + /* adjust for active gain scale + * The tsl2x7x_device_lux tables have a factor of 256 built-in. + * User-specified gain provides a multiplier. + * Apply user-specified gain before shifting right to retain precision. + * Use 64 bits to avoid overflow on multiplication. + * Then go back to 32 bits before division to avoid using div_u64(). + */ + + lux64 = lux; + lux64 = lux64 * chip->tsl2x7x_settings.als_gain_trim; + lux64 >>= 8; + lux = lux64; + lux = (lux + 500) / 1000; + + if (lux > TSL2X7X_LUX_CALC_OVER_FLOW) /* check for overflow */ + lux = TSL2X7X_LUX_CALC_OVER_FLOW; + + /* Update the structure with the latest lux. */ +return_max: + chip->als_cur_info.lux = lux; + ret = lux; + +out_unlock: + mutex_unlock(&chip->als_mutex); + + return ret; +} + +/** + * tsl2x7x_get_prox() - Reads proximity data registers and updates + * chip->prox_data. + * + * @indio_dev: pointer to IIO device + */ +static int tsl2x7x_get_prox(struct iio_dev *indio_dev) +{ + int i; + int ret; + u8 status; + u8 chdata[2]; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (mutex_trylock(&chip->prox_mutex) == 0) { + dev_err(&chip->client->dev, + "%s: Can't get prox mutex\n", __func__); + return -EBUSY; + } + + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_STATUS), &status); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: i2c err=%d\n", __func__, ret); + goto prox_poll_err; + } + + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + if (!(status & TSL2X7X_STA_ADC_VALID)) + goto prox_poll_err; + break; + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + if (!(status & TSL2X7X_STA_PRX_VALID)) + goto prox_poll_err; + break; + } + + for (i = 0; i < 2; i++) { + ret = tsl2x7x_i2c_read(chip->client, + (TSL2X7X_CMD_REG | + (TSL2X7X_PRX_LO + i)), &chdata[i]); + if (ret < 0) + goto prox_poll_err; + } + + chip->prox_data = + le16_to_cpup((const __le16 *)&chdata[0]); + +prox_poll_err: + + mutex_unlock(&chip->prox_mutex); + + return chip->prox_data; +} + +/** + * tsl2x7x_defaults() - Populates the device nominal operating parameters + * with those provided by a 'platform' data struct or + * with prefined defaults. + * + * @chip: pointer to device structure. + */ +static void tsl2x7x_defaults(struct tsl2X7X_chip *chip) +{ + /* If Operational settings defined elsewhere.. */ + if (chip->pdata && chip->pdata->platform_default_settings != 0) + memcpy(&(chip->tsl2x7x_settings), + chip->pdata->platform_default_settings, + sizeof(tsl2x7x_default_settings)); + else + memcpy(&(chip->tsl2x7x_settings), + &tsl2x7x_default_settings, + sizeof(tsl2x7x_default_settings)); + + /* Load up the proper lux table. */ + if (chip->pdata && chip->pdata->platform_lux_table[0].ratio != 0) + memcpy(chip->tsl2x7x_device_lux, + chip->pdata->platform_lux_table, + sizeof(chip->pdata->platform_lux_table)); + else + memcpy(chip->tsl2x7x_device_lux, + (struct tsl2x7x_lux *)tsl2x7x_default_lux_table_group[chip->id], + MAX_DEFAULT_TABLE_BYTES); +} + +/** + * tsl2x7x_als_calibrate() - Obtain single reading and calculate + * the als_gain_trim. + * + * @indio_dev: pointer to IIO device + */ +static int tsl2x7x_als_calibrate(struct iio_dev *indio_dev) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 reg_val; + int gain_trim_val; + int ret; + int lux_val; + + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to write CNTRL register, ret=%d\n", + __func__, ret); + return ret; + } + + reg_val = i2c_smbus_read_byte(chip->client); + if ((reg_val & (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) + != (TSL2X7X_CNTL_ADC_ENBL | TSL2X7X_CNTL_PWR_ON)) { + dev_err(&chip->client->dev, + "%s: failed: ADC not enabled\n", __func__); + return -1; + } + + ret = i2c_smbus_write_byte(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed to write ctrl reg: ret=%d\n", + __func__, ret); + return ret; + } + + reg_val = i2c_smbus_read_byte(chip->client); + if ((reg_val & TSL2X7X_STA_ADC_VALID) != TSL2X7X_STA_ADC_VALID) { + dev_err(&chip->client->dev, + "%s: failed: STATUS - ADC not valid.\n", __func__); + return -ENODATA; + } + + lux_val = tsl2x7x_get_lux(indio_dev); + if (lux_val < 0) { + dev_err(&chip->client->dev, + "%s: failed to get lux\n", __func__); + return lux_val; + } + + gain_trim_val = (((chip->tsl2x7x_settings.als_cal_target) + * chip->tsl2x7x_settings.als_gain_trim) / lux_val); + if ((gain_trim_val < 250) || (gain_trim_val > 4000)) + return -ERANGE; + + chip->tsl2x7x_settings.als_gain_trim = gain_trim_val; + dev_info(&chip->client->dev, + "%s als_calibrate completed\n", chip->client->name); + + return (int) gain_trim_val; +} + +static int tsl2x7x_chip_on(struct iio_dev *indio_dev) +{ + int i; + int ret = 0; + u8 *dev_reg; + u8 utmp; + int als_count; + int als_time; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 reg_val = 0; + + if (chip->pdata && chip->pdata->power_on) + chip->pdata->power_on(indio_dev); + + /* Non calculated parameters */ + chip->tsl2x7x_config[TSL2X7X_PRX_TIME] = + chip->tsl2x7x_settings.prx_time; + chip->tsl2x7x_config[TSL2X7X_WAIT_TIME] = + chip->tsl2x7x_settings.wait_time; + chip->tsl2x7x_config[TSL2X7X_PRX_CONFIG] = + chip->tsl2x7x_settings.prox_config; + + chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHLO] = + (chip->tsl2x7x_settings.als_thresh_low) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MINTHRESHHI] = + (chip->tsl2x7x_settings.als_thresh_low >> 8) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHLO] = + (chip->tsl2x7x_settings.als_thresh_high) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_ALS_MAXTHRESHHI] = + (chip->tsl2x7x_settings.als_thresh_high >> 8) & 0xFF; + chip->tsl2x7x_config[TSL2X7X_PERSISTENCE] = + chip->tsl2x7x_settings.persistence; + + chip->tsl2x7x_config[TSL2X7X_PRX_COUNT] = + chip->tsl2x7x_settings.prox_pulse_count; + chip->tsl2x7x_config[TSL2X7X_PRX_MINTHRESHLO] = + chip->tsl2x7x_settings.prox_thres_low; + chip->tsl2x7x_config[TSL2X7X_PRX_MAXTHRESHLO] = + chip->tsl2x7x_settings.prox_thres_high; + + /* and make sure we're not already on */ + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { + /* if forcing a register update - turn off, then on */ + dev_info(&chip->client->dev, "device is already enabled\n"); + return -EINVAL; + } + + /* determine als integration regster */ + als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270; + if (als_count == 0) + als_count = 1; /* ensure at least one cycle */ + + /* convert back to time (encompasses overrides) */ + als_time = (als_count * 27 + 5) / 10; + chip->tsl2x7x_config[TSL2X7X_ALS_TIME] = 256 - als_count; + + /* Set the gain based on tsl2x7x_settings struct */ + chip->tsl2x7x_config[TSL2X7X_GAIN] = + (chip->tsl2x7x_settings.als_gain | + (TSL2X7X_mA100 | TSL2X7X_DIODE1) + | ((chip->tsl2x7x_settings.prox_gain) << 2)); + + /* set chip struct re scaling and saturation */ + chip->als_saturation = als_count * 922; /* 90% of full scale */ + chip->als_time_scale = (als_time + 25) / 50; + + /* TSL2X7X Specific power-on / adc enable sequence + * Power on the device 1st. */ + utmp = TSL2X7X_CNTL_PWR_ON; + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on CNTRL reg.\n", __func__); + return ret; + } + + /* Use the following shadow copy for our delay before enabling ADC. + * Write all the registers. */ + for (i = 0, dev_reg = chip->tsl2x7x_config; + i < TSL2X7X_MAX_CONFIG_REG; i++) { + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG + i, *dev_reg++); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on write to reg %d.\n", __func__, i); + return ret; + } + } + + mdelay(3); /* Power-on settling time */ + + /* NOW enable the ADC + * initialize the desired mode of operation */ + utmp = TSL2X7X_CNTL_PWR_ON | + TSL2X7X_CNTL_ADC_ENBL | + TSL2X7X_CNTL_PROX_DET_ENBL; + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, utmp); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: failed on 2nd CTRL reg.\n", __func__); + return ret; + } + + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_WORKING; + + if (chip->tsl2x7x_settings.interrupts_en != 0) { + dev_info(&chip->client->dev, "Setting Up Interrupt(s)\n"); + + reg_val = TSL2X7X_CNTL_PWR_ON | TSL2X7X_CNTL_ADC_ENBL; + if ((chip->tsl2x7x_settings.interrupts_en == 0x20) || + (chip->tsl2x7x_settings.interrupts_en == 0x30)) + reg_val |= TSL2X7X_CNTL_PROX_DET_ENBL; + + reg_val |= chip->tsl2x7x_settings.interrupts_en; + ret = i2c_smbus_write_byte_data(chip->client, + (TSL2X7X_CMD_REG | TSL2X7X_CNTRL), reg_val); + if (ret < 0) + dev_err(&chip->client->dev, + "%s: failed in tsl2x7x_IOCTL_INT_SET.\n", + __func__); + + /* Clear out any initial interrupts */ + ret = i2c_smbus_write_byte(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); + if (ret < 0) { + dev_err(&chip->client->dev, + "%s: Failed to clear Int status\n", + __func__); + return ret; + } + } + + return ret; +} + +static int tsl2x7x_chip_off(struct iio_dev *indio_dev) +{ + int ret; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + /* turn device off */ + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; + + ret = i2c_smbus_write_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CNTRL, 0x00); + + if (chip->pdata && chip->pdata->power_off) + chip->pdata->power_off(chip->client); + + return ret; +} + +/** + * tsl2x7x_invoke_change + * @indio_dev: pointer to IIO device + * + * Obtain and lock both ALS and PROX resources, + * determine and save device state (On/Off), + * cycle device to implement updated parameter, + * put device back into proper state, and unlock + * resource. + */ +static +int tsl2x7x_invoke_change(struct iio_dev *indio_dev) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int device_status = chip->tsl2x7x_chip_status; + + mutex_lock(&chip->als_mutex); + mutex_lock(&chip->prox_mutex); + + if (device_status == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + tsl2x7x_chip_on(indio_dev); + + if (device_status != TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + mutex_unlock(&chip->prox_mutex); + mutex_unlock(&chip->als_mutex); + + return 0; +} + +static +void tsl2x7x_prox_calculate(int *data, int length, + struct tsl2x7x_prox_stat *statP) +{ + int i; + int sample_sum; + int tmp; + + if (length == 0) + length = 1; + + sample_sum = 0; + statP->min = INT_MAX; + statP->max = INT_MIN; + for (i = 0; i < length; i++) { + sample_sum += data[i]; + statP->min = min(statP->min, data[i]); + statP->max = max(statP->max, data[i]); + } + + statP->mean = sample_sum / length; + sample_sum = 0; + for (i = 0; i < length; i++) { + tmp = data[i] - statP->mean; + sample_sum += tmp * tmp; + } + statP->stddev = int_sqrt((long)sample_sum)/length; +} + +/** + * tsl2x7x_prox_cal() - Calculates std. and sets thresholds. + * @indio_dev: pointer to IIO device + * + * Calculates a standard deviation based on the samples, + * and sets the threshold accordingly. + */ +static void tsl2x7x_prox_cal(struct iio_dev *indio_dev) +{ + int prox_history[MAX_SAMPLES_CAL + 1]; + int i; + struct tsl2x7x_prox_stat prox_stat_data[2]; + struct tsl2x7x_prox_stat *calP; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + u8 tmp_irq_settings; + u8 current_state = chip->tsl2x7x_chip_status; + + if (chip->tsl2x7x_settings.prox_max_samples_cal > MAX_SAMPLES_CAL) { + dev_err(&chip->client->dev, + "%s: max prox samples cal is too big: %d\n", + __func__, chip->tsl2x7x_settings.prox_max_samples_cal); + chip->tsl2x7x_settings.prox_max_samples_cal = MAX_SAMPLES_CAL; + } + + /* have to stop to change settings */ + tsl2x7x_chip_off(indio_dev); + + /* Enable proximity detection save just in case prox not wanted yet*/ + tmp_irq_settings = chip->tsl2x7x_settings.interrupts_en; + chip->tsl2x7x_settings.interrupts_en |= TSL2X7X_CNTL_PROX_INT_ENBL; + + /*turn on device if not already on*/ + tsl2x7x_chip_on(indio_dev); + + /*gather the samples*/ + for (i = 0; i < chip->tsl2x7x_settings.prox_max_samples_cal; i++) { + mdelay(15); + tsl2x7x_get_prox(indio_dev); + prox_history[i] = chip->prox_data; + dev_info(&chip->client->dev, "2 i=%d prox data= %d\n", + i, chip->prox_data); + } + + tsl2x7x_chip_off(indio_dev); + calP = &prox_stat_data[PROX_STAT_CAL]; + tsl2x7x_prox_calculate(prox_history, + chip->tsl2x7x_settings.prox_max_samples_cal, calP); + chip->tsl2x7x_settings.prox_thres_high = (calP->max << 1) - calP->mean; + + dev_info(&chip->client->dev, " cal min=%d mean=%d max=%d\n", + calP->min, calP->mean, calP->max); + dev_info(&chip->client->dev, + "%s proximity threshold set to %d\n", + chip->client->name, chip->tsl2x7x_settings.prox_thres_high); + + /* back to the way they were */ + chip->tsl2x7x_settings.interrupts_en = tmp_irq_settings; + if (current_state == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_on(indio_dev); +} + +static ssize_t tsl2x7x_power_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + + return snprintf(buf, PAGE_SIZE, "%d\n", chip->tsl2x7x_chip_status); +} + +static ssize_t tsl2x7x_power_state_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_chip_on(indio_dev); + else + tsl2x7x_chip_off(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_gain_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128"); + break; + } + + return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120"); +} + +static ssize_t tsl2x7x_prox_gain_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", "1 2 4 8"); +} + +static ssize_t tsl2x7x_als_time_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + int y, z; + + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * TSL2X7X_MIN_ITIME; + y /= 1000; + z %= 1000; + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_als_time_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2x7x_parse_result result; + + result.integer = 0; + result.fract = 0; + + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + result.fract /= 3; + chip->tsl2x7x_settings.als_time = + (TSL2X7X_MAX_TIMER_CNT - (u8)result.fract); + + dev_info(&chip->client->dev, "%s: als time = %d", + __func__, chip->tsl2x7x_settings.als_time); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static IIO_CONST_ATTR(in_illuminance0_integration_time_available, + ".00272 - .696"); + +static ssize_t tsl2x7x_als_cal_target_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + + return snprintf(buf, PAGE_SIZE, "%d\n", + chip->tsl2x7x_settings.als_cal_target); +} + +static ssize_t tsl2x7x_als_cal_target_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + unsigned long value; + + if (kstrtoul(buf, 0, &value)) + return -EINVAL; + + if (value) + chip->tsl2x7x_settings.als_cal_target = value; + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +/* persistence settings */ +static ssize_t tsl2x7x_als_persistence_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + int y, z, filter_delay; + + /* Determine integration time */ + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * TSL2X7X_MIN_ITIME; + filter_delay = z * (chip->tsl2x7x_settings.persistence & 0x0F); + y = (filter_delay / 1000); + z = (filter_delay % 1000); + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_als_persistence_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2x7x_parse_result result; + int y, z, filter_delay; + + result.integer = 0; + result.fract = 0; + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.als_time) + 1; + z = y * TSL2X7X_MIN_ITIME; + + filter_delay = + DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + + chip->tsl2x7x_settings.persistence &= 0xF0; + chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F); + + dev_info(&chip->client->dev, "%s: als persistence = %d", + __func__, filter_delay); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static ssize_t tsl2x7x_prox_persistence_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + int y, z, filter_delay; + + /* Determine integration time */ + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; + z = y * TSL2X7X_MIN_ITIME; + filter_delay = z * ((chip->tsl2x7x_settings.persistence & 0xF0) >> 4); + y = (filter_delay / 1000); + z = (filter_delay % 1000); + + return snprintf(buf, PAGE_SIZE, "%d.%03d\n", y, z); +} + +static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + struct tsl2x7x_parse_result result; + int y, z, filter_delay; + + result.integer = 0; + result.fract = 0; + tsl2x7x_parse_buffer(buf, &result); + + result.fract /= 1000; + y = (TSL2X7X_MAX_TIMER_CNT - (u8)chip->tsl2x7x_settings.prx_time) + 1; + z = y * TSL2X7X_MIN_ITIME; + + filter_delay = + DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + + chip->tsl2x7x_settings.persistence &= 0x0F; + chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0); + + dev_info(&chip->client->dev, "%s: prox persistence = %d", + __func__, filter_delay); + + tsl2x7x_invoke_change(indio_dev); + + return IIO_VAL_INT_PLUS_MICRO; +} + +static ssize_t tsl2x7x_do_calibrate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_als_calibrate(indio_dev); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_luxtable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tsl2X7X_chip *chip = iio_priv(dev_to_iio_dev(dev)); + int i = 0; + int offset = 0; + + while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) { + offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,", + chip->tsl2x7x_device_lux[i].ratio, + chip->tsl2x7x_device_lux[i].ch0, + chip->tsl2x7x_device_lux[i].ch1); + if (chip->tsl2x7x_device_lux[i].ratio == 0) { + /* We just printed the first "0" entry. + * Now get rid of the extra "," and break. */ + offset--; + break; + } + i++; + } + + offset += snprintf(buf + offset, PAGE_SIZE, "\n"); + return offset; +} + +static ssize_t tsl2x7x_luxtable_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int value[ARRAY_SIZE(chip->tsl2x7x_device_lux)*3 + 1]; + int n; + + get_options(buf, ARRAY_SIZE(value), value); + + /* We now have an array of ints starting at value[1], and + * enumerated by value[0]. + * We expect each group of three ints is one table entry, + * and the last table entry is all 0. + */ + n = value[0]; + if ((n % 3) || n < 6 || + n > ((ARRAY_SIZE(chip->tsl2x7x_device_lux) - 1) * 3)) { + dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n); + return -EINVAL; + } + + if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) { + dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n); + return -EINVAL; + } + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) + tsl2x7x_chip_off(indio_dev); + + /* Zero out the table */ + memset(chip->tsl2x7x_device_lux, 0, sizeof(chip->tsl2x7x_device_lux)); + memcpy(chip->tsl2x7x_device_lux, &value[1], (value[0] * 4)); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + bool value; + + if (strtobool(buf, &value)) + return -EINVAL; + + if (value) + tsl2x7x_prox_cal(indio_dev); + + tsl2x7x_invoke_change(indio_dev); + + return len; +} + +static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev, + u64 event_code) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret; + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) + ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10); + else + ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20); + + return ret; +} + +static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + if (val) + chip->tsl2x7x_settings.interrupts_en |= 0x10; + else + chip->tsl2x7x_settings.interrupts_en &= 0x20; + } else { + if (val) + chip->tsl2x7x_settings.interrupts_en |= 0x20; + else + chip->tsl2x7x_settings.interrupts_en &= 0x10; + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static int tsl2x7x_write_thresh(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + chip->tsl2x7x_settings.als_thresh_high = val; + break; + case IIO_EV_DIR_FALLING: + chip->tsl2x7x_settings.als_thresh_low = val; + break; + default: + return -EINVAL; + } + } else { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + chip->tsl2x7x_settings.prox_thres_high = val; + break; + case IIO_EV_DIR_FALLING: + chip->tsl2x7x_settings.prox_thres_low = val; + break; + default: + return -EINVAL; + } + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static int tsl2x7x_read_thresh(struct iio_dev *indio_dev, + u64 event_code, + int *val) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + *val = chip->tsl2x7x_settings.als_thresh_high; + break; + case IIO_EV_DIR_FALLING: + *val = chip->tsl2x7x_settings.als_thresh_low; + break; + default: + return -EINVAL; + } + } else { + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_RISING: + *val = chip->tsl2x7x_settings.prox_thres_high; + break; + case IIO_EV_DIR_FALLING: + *val = chip->tsl2x7x_settings.prox_thres_low; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int tsl2x7x_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + int ret = -EINVAL; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + switch (chan->type) { + case IIO_LIGHT: + tsl2x7x_get_lux(indio_dev); + *val = chip->als_cur_info.lux; + ret = IIO_VAL_INT; + break; + default: + return -EINVAL; + break; + } + break; + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_INTENSITY: + tsl2x7x_get_lux(indio_dev); + if (chan->channel == 0) + *val = chip->als_cur_info.als_ch0; + else + *val = chip->als_cur_info.als_ch1; + ret = IIO_VAL_INT; + break; + case IIO_PROXIMITY: + tsl2x7x_get_prox(indio_dev); + *val = chip->prox_data; + ret = IIO_VAL_INT; + break; + default: + return -EINVAL; + break; + } + break; + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_LIGHT) + *val = + tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]; + else + *val = + tsl2X7X_prx_gainadj[chip->tsl2x7x_settings.prox_gain]; + ret = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_CALIBBIAS: + *val = chip->tsl2x7x_settings.als_gain_trim; + ret = IIO_VAL_INT; + break; + + default: + ret = -EINVAL; + } + + return ret; +} + +static int tsl2x7x_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_INTENSITY) { + switch (val) { + case 1: + chip->tsl2x7x_settings.als_gain = 0; + break; + case 8: + chip->tsl2x7x_settings.als_gain = 1; + break; + case 16: + chip->tsl2x7x_settings.als_gain = 2; + break; + case 120: + switch (chip->id) { + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + return -EINVAL; + break; + } + chip->tsl2x7x_settings.als_gain = 3; + break; + case 128: + switch (chip->id) { + case tsl2571: + case tsl2671: + case tmd2671: + case tsl2771: + case tmd2771: + return -EINVAL; + break; + } + chip->tsl2x7x_settings.als_gain = 3; + break; + default: + return -EINVAL; + } + } else { + switch (val) { + case 1: + chip->tsl2x7x_settings.prox_gain = 0; + break; + case 2: + chip->tsl2x7x_settings.prox_gain = 1; + break; + case 4: + chip->tsl2x7x_settings.prox_gain = 2; + break; + case 8: + chip->tsl2x7x_settings.prox_gain = 3; + break; + default: + return -EINVAL; + } + } + break; + case IIO_CHAN_INFO_CALIBBIAS: + chip->tsl2x7x_settings.als_gain_trim = val; + break; + + default: + return -EINVAL; + } + + tsl2x7x_invoke_change(indio_dev); + + return 0; +} + +static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, + tsl2x7x_power_state_show, tsl2x7x_power_state_store); + +static DEVICE_ATTR(in_proximity0_calibscale_available, S_IRUGO, + tsl2x7x_prox_gain_available_show, NULL); + +static DEVICE_ATTR(in_illuminance0_calibscale_available, S_IRUGO, + tsl2x7x_gain_available_show, NULL); + +static DEVICE_ATTR(in_illuminance0_integration_time, S_IRUGO | S_IWUSR, + tsl2x7x_als_time_show, tsl2x7x_als_time_store); + +static DEVICE_ATTR(in_illuminance0_target_input, S_IRUGO | S_IWUSR, + tsl2x7x_als_cal_target_show, tsl2x7x_als_cal_target_store); + +static DEVICE_ATTR(in_illuminance0_calibrate, S_IWUSR, NULL, + tsl2x7x_do_calibrate); + +static DEVICE_ATTR(in_proximity0_calibrate, S_IWUSR, NULL, + tsl2x7x_do_prox_calibrate); + +static DEVICE_ATTR(in_illuminance0_lux_table, S_IRUGO | S_IWUSR, + tsl2x7x_luxtable_show, tsl2x7x_luxtable_store); + +static DEVICE_ATTR(in_intensity0_thresh_period, S_IRUGO | S_IWUSR, + tsl2x7x_als_persistence_show, tsl2x7x_als_persistence_store); + +static DEVICE_ATTR(in_proximity0_thresh_period, S_IRUGO | S_IWUSR, + tsl2x7x_prox_persistence_show, tsl2x7x_prox_persistence_store); + +/* Use the default register values to identify the Taos device */ +static int tsl2x7x_device_id(unsigned char *id, int target) +{ + switch (target) { + case tsl2571: + case tsl2671: + case tsl2771: + return ((*id & 0xf0) == TRITON_ID); + break; + case tmd2671: + case tmd2771: + return ((*id & 0xf0) == HALIBUT_ID); + break; + case tsl2572: + case tsl2672: + case tmd2672: + case tsl2772: + case tmd2772: + return ((*id & 0xf0) == SWORDFISH_ID); + break; + } + + return -EINVAL; +} + +static irqreturn_t tsl2x7x_event_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + s64 timestamp = iio_get_time_ns(); + int ret; + u8 value; + + value = i2c_smbus_read_byte_data(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_STATUS); + + /* What type of interrupt do we need to process */ + if (value & TSL2X7X_STA_PRX_INTR) { + tsl2x7x_get_prox(indio_dev); /* freshen data for ABI */ + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + } + + if (value & TSL2X7X_STA_ALS_INTR) { + tsl2x7x_get_lux(indio_dev); /* freshen data for ABI */ + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + } + /* Clear interrupt now that we have handled it. */ + ret = i2c_smbus_write_byte(chip->client, + TSL2X7X_CMD_REG | TSL2X7X_CMD_SPL_FN | + TSL2X7X_CMD_PROXALS_INT_CLR); + if (ret < 0) + dev_err(&chip->client->dev, + "%s: Failed to clear irq from event handler. err = %d\n", + __func__, ret); + + return IRQ_HANDLED; +} + +static struct attribute *tsl2x7x_ALS_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + NULL +}; + +static struct attribute *tsl2x7x_PRX_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_proximity0_calibrate.attr, + NULL +}; + +static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + &dev_attr_in_proximity0_calibrate.attr, + NULL +}; + +static struct attribute *tsl2x7x_PRX2_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_proximity0_calibrate.attr, + &dev_attr_in_proximity0_calibscale_available.attr, + NULL +}; + +static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { + &dev_attr_power_state.attr, + &dev_attr_in_illuminance0_calibscale_available.attr, + &dev_attr_in_illuminance0_integration_time.attr, + &iio_const_attr_in_illuminance0_integration_time_available\ + .dev_attr.attr, + &dev_attr_in_illuminance0_target_input.attr, + &dev_attr_in_illuminance0_calibrate.attr, + &dev_attr_in_illuminance0_lux_table.attr, + &dev_attr_in_proximity0_calibrate.attr, + &dev_attr_in_proximity0_calibscale_available.attr, + NULL +}; + +static struct attribute *tsl2X7X_ALS_event_attrs[] = { + &dev_attr_in_intensity0_thresh_period.attr, + NULL, +}; +static struct attribute *tsl2X7X_PRX_event_attrs[] = { + &dev_attr_in_proximity0_thresh_period.attr, + NULL, +}; + +static struct attribute *tsl2X7X_ALSPRX_event_attrs[] = { + &dev_attr_in_intensity0_thresh_period.attr, + &dev_attr_in_proximity0_thresh_period.attr, + NULL, +}; + +static const struct attribute_group tsl2X7X_device_attr_group_tbl[] = { + [ALS] = { + .attrs = tsl2x7x_ALS_device_attrs, + }, + [PRX] = { + .attrs = tsl2x7x_PRX_device_attrs, + }, + [ALSPRX] = { + .attrs = tsl2x7x_ALSPRX_device_attrs, + }, + [PRX2] = { + .attrs = tsl2x7x_PRX2_device_attrs, + }, + [ALSPRX2] = { + .attrs = tsl2x7x_ALSPRX2_device_attrs, + }, +}; + +static struct attribute_group tsl2X7X_event_attr_group_tbl[] = { + [ALS] = { + .attrs = tsl2X7X_ALS_event_attrs, + .name = "events", + }, + [PRX] = { + .attrs = tsl2X7X_PRX_event_attrs, + .name = "events", + }, + [ALSPRX] = { + .attrs = tsl2X7X_ALSPRX_event_attrs, + .name = "events", + }, +}; + +static const struct iio_info tsl2X7X_device_info[] = { + [ALS] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALS], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALS], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [PRX] = { + .attrs = &tsl2X7X_device_attr_group_tbl[PRX], + .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [ALSPRX] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [PRX2] = { + .attrs = &tsl2X7X_device_attr_group_tbl[PRX2], + .event_attrs = &tsl2X7X_event_attr_group_tbl[PRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, + [ALSPRX2] = { + .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2], + .event_attrs = &tsl2X7X_event_attr_group_tbl[ALSPRX], + .driver_module = THIS_MODULE, + .read_raw = &tsl2x7x_read_raw, + .write_raw = &tsl2x7x_write_raw, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, + }, +}; + +static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = { + [ALS] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + }, + }, + .chan_table_elements = 3, + .info = &tsl2X7X_device_info[ALS], + }, + [PRX] = { + .channel = { + { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 1, + .info = &tsl2X7X_device_info[PRX], + }, + [ALSPRX] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 4, + .info = &tsl2X7X_device_info[ALSPRX], + }, + [PRX2] = { + .channel = { + { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 1, + .info = &tsl2X7X_device_info[PRX2], + }, + [ALSPRX2] = { + .channel = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_PROCESSED_SEPARATE_BIT, + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, { + .type = IIO_INTENSITY, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, + }, { + .type = IIO_PROXIMITY, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, + .event_mask = TSL2X7X_EVENT_MASK + }, + }, + .chan_table_elements = 4, + .info = &tsl2X7X_device_info[ALSPRX2], + }, +}; + +static int __devinit tsl2x7x_probe(struct i2c_client *clientp, + const struct i2c_device_id *id) +{ + int ret; + unsigned char device_id; + struct iio_dev *indio_dev; + struct tsl2X7X_chip *chip; + + indio_dev = iio_device_alloc(sizeof(*chip)); + if (!indio_dev) + return -ENOMEM; + + chip = iio_priv(indio_dev); + chip->client = clientp; + i2c_set_clientdata(clientp, indio_dev); + + ret = tsl2x7x_i2c_read(chip->client, + TSL2X7X_CHIPID, &device_id); + if (ret < 0) + goto fail1; + + if ((!tsl2x7x_device_id(&device_id, id->driver_data)) || + (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) { + dev_info(&chip->client->dev, + "%s: i2c device found does not match expected id\n", + __func__); + goto fail1; + } + + ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL)); + if (ret < 0) { + dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n", + __func__, ret); + goto fail1; + } + + /* ALS and PROX functions can be invoked via user space poll + * or H/W interrupt. If busy return last sample. */ + mutex_init(&chip->als_mutex); + mutex_init(&chip->prox_mutex); + + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_UNKNOWN; + chip->pdata = clientp->dev.platform_data; + chip->id = id->driver_data; + chip->chip_info = + &tsl2x7x_chip_info_tbl[device_channel_config[id->driver_data]]; + + indio_dev->info = chip->chip_info->info; + indio_dev->dev.parent = &clientp->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = chip->client->name; + indio_dev->channels = chip->chip_info->channel; + indio_dev->num_channels = chip->chip_info->chan_table_elements; + + if (clientp->irq) { + ret = request_threaded_irq(clientp->irq, + NULL, + &tsl2x7x_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "TSL2X7X_event", + indio_dev); + if (ret) { + dev_err(&clientp->dev, + "%s: irq request failed", __func__); + goto fail2; + } + } + + /* Load up the defaults */ + tsl2x7x_defaults(chip); + /* Make sure the chip is on */ + tsl2x7x_chip_on(indio_dev); + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&clientp->dev, + "%s: iio registration failed\n", __func__); + goto fail1; + } + + dev_info(&clientp->dev, "%s Light sensor found.\n", id->name); + + return 0; + +fail1: + if (clientp->irq) + free_irq(clientp->irq, indio_dev); +fail2: + iio_device_free(indio_dev); + + return ret; +} + +static int tsl2x7x_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret = 0; + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_WORKING) { + ret = tsl2x7x_chip_off(indio_dev); + chip->tsl2x7x_chip_status = TSL2X7X_CHIP_SUSPENDED; + } + + if (chip->pdata && chip->pdata->platform_power) { + pm_message_t pmm = {PM_EVENT_SUSPEND}; + chip->pdata->platform_power(dev, pmm); + } + + return ret; +} + +static int tsl2x7x_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct tsl2X7X_chip *chip = iio_priv(indio_dev); + int ret = 0; + + if (chip->pdata && chip->pdata->platform_power) { + pm_message_t pmm = {PM_EVENT_RESUME}; + chip->pdata->platform_power(dev, pmm); + } + + if (chip->tsl2x7x_chip_status == TSL2X7X_CHIP_SUSPENDED) + ret = tsl2x7x_chip_on(indio_dev); + + return ret; +} + +static int __devexit tsl2x7x_remove(struct i2c_client *client) +{ + struct tsl2X7X_chip *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = iio_priv_to_dev(chip); + + tsl2x7x_chip_off(indio_dev); + + iio_device_unregister(indio_dev); + if (client->irq) + free_irq(client->irq, chip->client->name); + + iio_device_free(indio_dev); + + return 0; +} + +static struct i2c_device_id tsl2x7x_idtable[] = { + { "tsl2571", tsl2571 }, + { "tsl2671", tsl2671 }, + { "tmd2671", tmd2671 }, + { "tsl2771", tsl2771 }, + { "tmd2771", tmd2771 }, + { "tsl2572", tsl2572 }, + { "tsl2672", tsl2672 }, + { "tmd2672", tmd2672 }, + { "tsl2772", tsl2772 }, + { "tmd2772", tmd2772 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tsl2x7x_idtable); + +static const struct dev_pm_ops tsl2x7x_pm_ops = { + .suspend = tsl2x7x_suspend, + .resume = tsl2x7x_resume, +}; + +/* Driver definition */ +static struct i2c_driver tsl2x7x_driver = { + .driver = { + .name = "tsl2x7x", + .pm = &tsl2x7x_pm_ops, + }, + .id_table = tsl2x7x_idtable, + .probe = tsl2x7x_probe, + .remove = __devexit_p(tsl2x7x_remove), +}; + +module_i2c_driver(tsl2x7x_driver); + +MODULE_AUTHOR("J. August Brenner<jbrenner@taosinc.com>"); +MODULE_DESCRIPTION("TAOS tsl2x7x ambient and proximity light sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/machine.h b/drivers/staging/iio/machine.h deleted file mode 100644 index 0b1f19b..0000000 --- a/drivers/staging/iio/machine.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Industrial I/O in kernel access map definitions for board files. - * - * Copyright (c) 2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -/** - * struct iio_map - description of link between consumer and device channels - * @adc_channel_label: Label used to identify the channel on the provider. - * This is matched against the datasheet_name element - * of struct iio_chan_spec. - * @consumer_dev_name: Name to uniquely identify the consumer device. - * @consumer_channel: Unique name used to idenitify the channel on the - * consumer side. - */ -struct iio_map { - const char *adc_channel_label; - const char *consumer_dev_name; - const char *consumer_channel; -}; diff --git a/drivers/staging/iio/magnetometer/Kconfig b/drivers/staging/iio/magnetometer/Kconfig index 722c4e1..b9d9325 100644 --- a/drivers/staging/iio/magnetometer/Kconfig +++ b/drivers/staging/iio/magnetometer/Kconfig @@ -15,13 +15,13 @@ config SENSORS_AK8975 will be called ak8975. config SENSORS_HMC5843 - tristate "Honeywell HMC5843 3-Axis Magnetometer" + tristate "Honeywell HMC5843/5883/5883L 3-Axis Magnetometer" depends on I2C help - Say Y here to add support for the Honeywell HMC 5843 3-Axis - Magnetometer (digital compass). + Say Y here to add support for the Honeywell HMC5843, HMC5883 and + HMC5883L 3-Axis Magnetometer (digital compass). To compile this driver as a module, choose M here: the module - will be called hmc5843 + will be called hmc5843. endmenu diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index ebc2d08..5834e4a 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -30,8 +30,8 @@ #include <linux/gpio.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> /* * Register definitions, as well as various shifts and masks to get at the * individual fields of the registers. @@ -242,7 +242,7 @@ static int ak8975_setup(struct i2c_client *client) static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ak8975_data *data = iio_priv(indio_dev); return sprintf(buf, "%u\n", data->mode); @@ -255,7 +255,7 @@ static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ak8975_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; bool value; @@ -431,7 +431,7 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, struct ak8975_data *data = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: return ak8975_read_axis(indio_dev, chan->address, val); case IIO_CHAN_INFO_SCALE: *val = data->raw_to_gauss[chan->address]; @@ -445,7 +445,8 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ .address = index, \ } @@ -505,7 +506,7 @@ static int ak8975_probe(struct i2c_client *client, } /* Register with IIO */ - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit_gpio; @@ -536,7 +537,7 @@ static int ak8975_probe(struct i2c_client *client, return 0; exit_free_iio: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit_gpio: if (gpio_is_valid(eoc_gpio)) gpio_free(eoc_gpio); @@ -554,7 +555,7 @@ static int ak8975_remove(struct i2c_client *client) if (gpio_is_valid(data->eoc_gpio)) gpio_free(data->eoc_gpio); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index e00b416..c1fa09f 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -2,6 +2,8 @@ Author: Shubhrajyoti Datta <shubhrajyoti@ti.com> Acknowledgement: Jonathan Cameron <jic23@cam.ac.uk> for valuable inputs. + Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,10 +24,8 @@ #include <linux/i2c.h> #include <linux/slab.h> #include <linux/types.h> -#include "../iio.h" -#include "../sysfs.h" - -#define HMC5843_I2C_ADDRESS 0x1E +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define HMC5843_CONFIG_REG_A 0x00 #define HMC5843_CONFIG_REG_B 0x01 @@ -36,110 +36,185 @@ #define HMC5843_DATA_OUT_Y_LSB_REG 0x06 #define HMC5843_DATA_OUT_Z_MSB_REG 0x07 #define HMC5843_DATA_OUT_Z_LSB_REG 0x08 +/* Beware: Y and Z are exchanged on HMC5883 */ +#define HMC5883_DATA_OUT_Z_MSB_REG 0x05 +#define HMC5883_DATA_OUT_Z_LSB_REG 0x06 +#define HMC5883_DATA_OUT_Y_MSB_REG 0x07 +#define HMC5883_DATA_OUT_Y_LSB_REG 0x08 #define HMC5843_STATUS_REG 0x09 #define HMC5843_ID_REG_A 0x0A #define HMC5843_ID_REG_B 0x0B #define HMC5843_ID_REG_C 0x0C +enum hmc5843_ids { + HMC5843_ID, + HMC5883_ID, + HMC5883L_ID, +}; + +/* + * Beware: identification of the HMC5883 is still "H43"; + * I2C address is also unchanged + */ #define HMC5843_ID_REG_LENGTH 0x03 #define HMC5843_ID_STRING "H43" +#define HMC5843_I2C_ADDRESS 0x1E /* - * Range settings in (+-)Ga - * */ -#define RANGE_GAIN_OFFSET 0x05 - -#define RANGE_0_7 0x00 -#define RANGE_1_0 0x01 /* default */ -#define RANGE_1_5 0x02 -#define RANGE_2_0 0x03 -#define RANGE_3_2 0x04 -#define RANGE_3_8 0x05 -#define RANGE_4_5 0x06 -#define RANGE_6_5 0x07 /* Not recommended */ + * Range gain settings in (+-)Ga + * Beware: HMC5843 and HMC5883 have different recommended sensor field + * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively + */ +#define HMC5843_RANGE_GAIN_OFFSET 0x05 +#define HMC5843_RANGE_GAIN_DEFAULT 0x01 +#define HMC5843_RANGE_GAIN_MAX 0x07 /* * Device status */ -#define DATA_READY 0x01 -#define DATA_OUTPUT_LOCK 0x02 -#define VOLTAGE_REGULATOR_ENABLED 0x04 +#define HMC5843_DATA_READY 0x01 +#define HMC5843_DATA_OUTPUT_LOCK 0x02 +/* Does not exist on HMC5883, not used */ +#define HMC5843_VOLTAGE_REGULATOR_ENABLED 0x04 /* * Mode register configuration */ -#define MODE_CONVERSION_CONTINUOUS 0x00 -#define MODE_CONVERSION_SINGLE 0x01 -#define MODE_IDLE 0x02 -#define MODE_SLEEP 0x03 - -/* Minimum Data Output Rate in 1/10 Hz */ -#define RATE_OFFSET 0x02 -#define RATE_BITMASK 0x1C -#define RATE_5 0x00 -#define RATE_10 0x01 -#define RATE_20 0x02 -#define RATE_50 0x03 -#define RATE_100 0x04 -#define RATE_200 0x05 -#define RATE_500 0x06 -#define RATE_NOT_USED 0x07 +#define HMC5843_MODE_CONVERSION_CONTINUOUS 0x00 +#define HMC5843_MODE_CONVERSION_SINGLE 0x01 +#define HMC5843_MODE_IDLE 0x02 +#define HMC5843_MODE_SLEEP 0x03 +#define HMC5843_MODE_MASK 0x03 + +/* + * HMC5843: Minimum data output rate + * HMC5883: Typical data output rate + */ +#define HMC5843_RATE_OFFSET 0x02 +#define HMC5843_RATE_BITMASK 0x1C +#define HMC5843_RATE_NOT_USED 0x07 /* - * Device Configuration + * Device measurement configuration */ -#define CONF_NORMAL 0x00 -#define CONF_POSITIVE_BIAS 0x01 -#define CONF_NEGATIVE_BIAS 0x02 -#define CONF_NOT_USED 0x03 -#define MEAS_CONF_MASK 0x03 +#define HMC5843_MEAS_CONF_NORMAL 0x00 +#define HMC5843_MEAS_CONF_POSITIVE_BIAS 0x01 +#define HMC5843_MEAS_CONF_NEGATIVE_BIAS 0x02 +#define HMC5843_MEAS_CONF_NOT_USED 0x03 +#define HMC5843_MEAS_CONF_MASK 0x03 -static int hmc5843_regval_to_nanoscale[] = { +/* + * Scaling factors: 10000000/Gain + */ +static const int hmc5843_regval_to_nanoscale[] = { 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714 }; -static const int regval_to_input_field_mg[] = { - 700, - 1000, - 1500, - 2000, - 3200, - 3800, - 4500, - 6500 +static const int hmc5883_regval_to_nanoscale[] = { + 7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662 }; -static const char * const regval_to_samp_freq[] = { - "0.5", - "1", - "2", - "5", - "10", - "20", - "50", + +static const int hmc5883l_regval_to_nanoscale[] = { + 7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478 +}; + +/* + * From the HMC5843 datasheet: + * Value | Sensor input field range (Ga) | Gain (counts/milli-Gauss) + * 0 | (+-)0.7 | 1620 + * 1 | (+-)1.0 | 1300 + * 2 | (+-)1.5 | 970 + * 3 | (+-)2.0 | 780 + * 4 | (+-)3.2 | 530 + * 5 | (+-)3.8 | 460 + * 6 | (+-)4.5 | 390 + * 7 | (+-)6.5 | 280 + * + * From the HMC5883 datasheet: + * Value | Recommended sensor field range (Ga) | Gain (counts/Gauss) + * 0 | (+-)0.9 | 1280 + * 1 | (+-)1.2 | 1024 + * 2 | (+-)1.9 | 768 + * 3 | (+-)2.5 | 614 + * 4 | (+-)4.0 | 415 + * 5 | (+-)4.6 | 361 + * 6 | (+-)5.5 | 307 + * 7 | (+-)7.9 | 219 + * + * From the HMC5883L datasheet: + * Value | Recommended sensor field range (Ga) | Gain (LSB/Gauss) + * 0 | (+-)0.88 | 1370 + * 1 | (+-)1.3 | 1090 + * 2 | (+-)1.9 | 820 + * 3 | (+-)2.5 | 660 + * 4 | (+-)4.0 | 440 + * 5 | (+-)4.7 | 390 + * 6 | (+-)5.6 | 330 + * 7 | (+-)8.1 | 230 + */ +static const int hmc5843_regval_to_input_field_mga[] = { + 700, 1000, 1500, 2000, 3200, 3800, 4500, 6500 +}; + +static const int hmc5883_regval_to_input_field_mga[] = { + 900, 1200, 1900, 2500, 4000, 4600, 5500, 7900 +}; + +static const int hmc5883l_regval_to_input_field_mga[] = { + 880, 1300, 1900, 2500, 4000, 4700, 5600, 8100 +}; + +/* + * From the datasheet: + * Value | HMC5843 | HMC5883/HMC5883L + * | Data output rate (Hz) | Data output rate (Hz) + * 0 | 0.5 | 0.75 + * 1 | 1 | 1.5 + * 2 | 2 | 3 + * 3 | 5 | 7.5 + * 4 | 10 (default) | 15 + * 5 | 20 | 30 + * 6 | 50 | 75 + * 7 | Not used | Not used + */ +static const char * const hmc5843_regval_to_sample_freq[] = { + "0.5", "1", "2", "5", "10", "20", "50", +}; + +static const char * const hmc5883_regval_to_sample_freq[] = { + "0.75", "1.5", "3", "7.5", "15", "30", "75", }; /* Addresses to scan: 0x1E */ static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS, - I2C_CLIENT_END }; + I2C_CLIENT_END }; + +/* Describe chip variants */ +struct hmc5843_chip_info { + const struct iio_chan_spec *channels; + int num_channels; + const char * const *regval_to_sample_freq; + const int *regval_to_input_field_mga; + const int *regval_to_nanoscale; +}; /* Each client has this additional data */ struct hmc5843_data { struct mutex lock; - u8 rate; - u8 meas_conf; - u8 operating_mode; - u8 range; + u8 rate; + u8 meas_conf; + u8 operating_mode; + u8 range; + const struct hmc5843_chip_info *variant; }; -static void hmc5843_init_client(struct i2c_client *client); - +/* The lower two bits contain the current conversion mode */ static s32 hmc5843_configure(struct i2c_client *client, u8 operating_mode) { - /* The lower two bits contain the current conversion mode */ return i2c_smbus_write_byte_data(client, HMC5843_MODE_REG, - (operating_mode & 0x03)); + operating_mode & HMC5843_MODE_MASK); } /* Return the measurement value from the specified channel */ @@ -153,7 +228,7 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev, mutex_lock(&data->lock); result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG); - while (!(result & DATA_READY)) + while (!(result & HMC5843_DATA_READY)) result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG); result = i2c_smbus_read_word_data(client, address); @@ -161,30 +236,29 @@ static int hmc5843_read_measurement(struct iio_dev *indio_dev, if (result < 0) return -EINVAL; - *val = (s16)swab16((u16)result); + *val = (s16)swab16((u16)result); return IIO_VAL_INT; } - /* - * From the datasheet + * From the datasheet: * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the - * device continuously performs conversions and places the result in the - * data register. + * device continuously performs conversions and places the result in + * the data register. * - * 1 - Single-Conversion Mode : device performs a single measurement, - * sets RDY high and returned to sleep mode + * 1 - Single-Conversion Mode : Device performs a single measurement, + * sets RDY high and returns to sleep mode. * - * 2 - Idle Mode : Device is placed in idle mode. + * 2 - Idle Mode : Device is placed in idle mode. * - * 3 - Sleep Mode. Device is placed in sleep mode. + * 3 - Sleep Mode : Device is placed in sleep mode. * */ static ssize_t hmc5843_show_operating_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct hmc5843_data *data = iio_priv(indio_dev); return sprintf(buf, "%d\n", data->operating_mode); } @@ -194,21 +268,22 @@ static ssize_t hmc5843_set_operating_mode(struct device *dev, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct hmc5843_data *data = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned long operating_mode = 0; s32 status; int error; + mutex_lock(&data->lock); - error = strict_strtoul(buf, 10, &operating_mode); + error = kstrtoul(buf, 10, &operating_mode); if (error) { count = error; goto exit; } - dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode); - if (operating_mode > MODE_SLEEP) { + dev_dbg(dev, "set conversion mode to %lu\n", operating_mode); + if (operating_mode > HMC5843_MODE_SLEEP) { count = -EINVAL; goto exit; } @@ -225,6 +300,7 @@ exit: mutex_unlock(&data->lock); return count; } + static IIO_DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, hmc5843_show_operating_mode, @@ -234,25 +310,29 @@ static IIO_DEVICE_ATTR(operating_mode, /* * API for setting the measurement configuration to * Normal, Positive bias and Negative bias - * From the datasheet * - * Normal measurement configuration (default): In normal measurement - * configuration the device follows normal measurement flow. Pins BP and BN - * are left floating and high impedance. + * From the datasheet: + * 0 - Normal measurement configuration (default): In normal measurement + * configuration the device follows normal measurement flow. Pins BP + * and BN are left floating and high impedance. * - * Positive bias configuration: In positive bias configuration, a positive - * current is forced across the resistive load on pins BP and BN. + * 1 - Positive bias configuration: In positive bias configuration, a + * positive current is forced across the resistive load on pins BP + * and BN. * - * Negative bias configuration. In negative bias configuration, a negative - * current is forced across the resistive load on pins BP and BN. + * 2 - Negative bias configuration. In negative bias configuration, a + * negative current is forced across the resistive load on pins BP + * and BN. * */ static s32 hmc5843_set_meas_conf(struct i2c_client *client, u8 meas_conf) { - struct hmc5843_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hmc5843_data *data = iio_priv(indio_dev); u8 reg_val; - reg_val = (meas_conf & MEAS_CONF_MASK) | (data->rate << RATE_OFFSET); + reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) | + (data->rate << HMC5843_RATE_OFFSET); return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val); } @@ -260,7 +340,7 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct hmc5843_data *data = iio_priv(indio_dev); return sprintf(buf, "%d\n", data->meas_conf); } @@ -270,16 +350,20 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); - struct hmc5843_data *data = i2c_get_clientdata(client); + struct hmc5843_data *data = iio_priv(indio_dev); unsigned long meas_conf = 0; - int error = strict_strtoul(buf, 10, &meas_conf); + int error; + + error = kstrtoul(buf, 10, &meas_conf); if (error) return error; - mutex_lock(&data->lock); + if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED) + return -EINVAL; - dev_dbg(dev, "set mode to %lu\n", meas_conf); + mutex_lock(&data->lock); + dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf); if (hmc5843_set_meas_conf(client, meas_conf)) { count = -EINVAL; goto exit; @@ -290,71 +374,85 @@ exit: mutex_unlock(&data->lock); return count; } + static IIO_DEVICE_ATTR(meas_conf, S_IWUSR | S_IRUGO, hmc5843_show_measurement_configuration, hmc5843_set_measurement_configuration, 0); -/* - * From Datasheet - * The table shows the minimum data output - * Value | Minimum data output rate(Hz) - * 0 | 0.5 - * 1 | 1 - * 2 | 2 - * 3 | 5 - * 4 | 10 (default) - * 5 | 20 - * 6 | 50 - * 7 | Not used - */ -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50"); +static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct hmc5843_data *data = iio_priv(indio_dev); + ssize_t total_n = 0; + int i; + + for (i = 0; i < HMC5843_RATE_NOT_USED; i++) { + ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]); + buf += n; + total_n += n; + } + /* replace trailing space by newline */ + buf[-1] = '\n'; + + return total_n; +} + +static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available); static s32 hmc5843_set_rate(struct i2c_client *client, u8 rate) { - struct hmc5843_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hmc5843_data *data = iio_priv(indio_dev); u8 reg_val; - reg_val = (data->meas_conf) | (rate << RATE_OFFSET); - if (rate >= RATE_NOT_USED) { + if (rate >= HMC5843_RATE_NOT_USED) { dev_err(&client->dev, - "This data output rate is not supported\n"); + "data output rate is not supported\n"); return -EINVAL; } + + reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET); return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val); } -static ssize_t set_sampling_frequency(struct device *dev, +static int hmc5843_check_sampling_frequency(struct hmc5843_data *data, + const char *buf) +{ + const char * const *samp_freq = data->variant->regval_to_sample_freq; + int i; + + for (i = 0; i < HMC5843_RATE_NOT_USED; i++) { + if (sysfs_streq(buf, samp_freq[i])) + return i; + } + + return -EINVAL; +} + +static ssize_t hmc5843_set_sampling_frequency(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct hmc5843_data *data = iio_priv(indio_dev); - unsigned long rate = 0; - - if (strncmp(buf, "0.5" , 3) == 0) - rate = RATE_5; - else if (strncmp(buf, "1" , 1) == 0) - rate = RATE_10; - else if (strncmp(buf, "2", 1) == 0) - rate = RATE_20; - else if (strncmp(buf, "5", 1) == 0) - rate = RATE_50; - else if (strncmp(buf, "10", 2) == 0) - rate = RATE_100; - else if (strncmp(buf, "20" , 2) == 0) - rate = RATE_200; - else if (strncmp(buf, "50" , 2) == 0) - rate = RATE_500; - else - return -EINVAL; + int rate; + + rate = hmc5843_check_sampling_frequency(data, buf); + if (rate < 0) { + dev_err(&client->dev, + "sampling frequency is not supported\n"); + return rate; + } mutex_lock(&data->lock); - dev_dbg(dev, "set rate to %lu\n", rate); + dev_dbg(dev, "set rate to %d\n", rate); if (hmc5843_set_rate(client, rate)) { count = -EINVAL; goto exit; @@ -366,89 +464,79 @@ exit: return count; } -static ssize_t show_sampling_frequency(struct device *dev, +static ssize_t hmc5843_show_sampling_frequency(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct hmc5843_data *data = iio_priv(indio_dev); s32 rate; - rate = i2c_smbus_read_byte_data(client, this_attr->address); + rate = i2c_smbus_read_byte_data(client, this_attr->address); if (rate < 0) return rate; - rate = (rate & RATE_BITMASK) >> RATE_OFFSET; - return sprintf(buf, "%s\n", regval_to_samp_freq[rate]); + rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET; + return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]); } + static IIO_DEVICE_ATTR(sampling_frequency, S_IWUSR | S_IRUGO, - show_sampling_frequency, - set_sampling_frequency, + hmc5843_show_sampling_frequency, + hmc5843_set_sampling_frequency, HMC5843_CONFIG_REG_A); -/* - * From Datasheet - * Nominal gain settings - * Value | Sensor Input Field Range(Ga) | Gain(counts/ milli-gauss) - *0 |(+-)0.7 |1620 - *1 |(+-)1.0 |1300 - *2 |(+-)1.5 |970 - *3 |(+-)2.0 |780 - *4 |(+-)3.2 |530 - *5 |(+-)3.8 |460 - *6 |(+-)4.5 |390 - *7 |(+-)6.5 |280 - */ -static ssize_t show_range(struct device *dev, +static ssize_t hmc5843_show_range_gain(struct device *dev, struct device_attribute *attr, char *buf) { u8 range; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct hmc5843_data *data = iio_priv(indio_dev); range = data->range; - return sprintf(buf, "%d\n", regval_to_input_field_mg[range]); + return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]); } -static ssize_t set_range(struct device *dev, +static ssize_t hmc5843_set_range_gain(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct hmc5843_data *data = iio_priv(indio_dev); unsigned long range = 0; int error; + mutex_lock(&data->lock); - error = strict_strtoul(buf, 10, &range); + error = kstrtoul(buf, 10, &range); if (error) { count = error; goto exit; } dev_dbg(dev, "set range to %lu\n", range); - if (range > RANGE_6_5) { + if (range > HMC5843_RANGE_GAIN_MAX) { count = -EINVAL; goto exit; } data->range = range; - range = range << RANGE_GAIN_OFFSET; + range = range << HMC5843_RANGE_GAIN_OFFSET; if (i2c_smbus_write_byte_data(client, this_attr->address, range)) count = -EINVAL; exit: mutex_unlock(&data->lock); return count; - } + static IIO_DEVICE_ATTR(in_magn_range, S_IWUSR | S_IRUGO, - show_range, - set_range, + hmc5843_show_range_gain, + hmc5843_set_range_gain, HMC5843_CONFIG_REG_B); static int hmc5843_read_raw(struct iio_dev *indio_dev, @@ -459,13 +547,13 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, struct hmc5843_data *data = iio_priv(indio_dev); switch (mask) { - case 0: + case IIO_CHAN_INFO_RAW: return hmc5843_read_measurement(indio_dev, chan->address, val); case IIO_CHAN_INFO_SCALE: *val = 0; - *val2 = hmc5843_regval_to_nanoscale[data->range]; + *val2 = data->variant->regval_to_nanoscale[data->range]; return IIO_VAL_INT_PLUS_NANO; }; return -EINVAL; @@ -476,7 +564,8 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, .type = IIO_MAGN, \ .modified = 1, \ .channel2 = IIO_MOD_##axis, \ - .info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .address = add \ } @@ -486,12 +575,18 @@ static const struct iio_chan_spec hmc5843_channels[] = { HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG), }; +static const struct iio_chan_spec hmc5883_channels[] = { + HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG), + HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG), + HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG), +}; + static struct attribute *hmc5843_attributes[] = { &iio_dev_attr_meas_conf.dev_attr.attr, &iio_dev_attr_operating_mode.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_dev_attr_in_magn_range.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, NULL }; @@ -499,6 +594,33 @@ static const struct attribute_group hmc5843_group = { .attrs = hmc5843_attributes, }; +static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = { + [HMC5843_ID] = { + .channels = hmc5843_channels, + .num_channels = ARRAY_SIZE(hmc5843_channels), + .regval_to_sample_freq = hmc5843_regval_to_sample_freq, + .regval_to_input_field_mga = + hmc5843_regval_to_input_field_mga, + .regval_to_nanoscale = hmc5843_regval_to_nanoscale, + }, + [HMC5883_ID] = { + .channels = hmc5883_channels, + .num_channels = ARRAY_SIZE(hmc5883_channels), + .regval_to_sample_freq = hmc5883_regval_to_sample_freq, + .regval_to_input_field_mga = + hmc5883_regval_to_input_field_mga, + .regval_to_nanoscale = hmc5883_regval_to_nanoscale, + }, + [HMC5883L_ID] = { + .channels = hmc5883_channels, + .num_channels = ARRAY_SIZE(hmc5883_channels), + .regval_to_sample_freq = hmc5883_regval_to_sample_freq, + .regval_to_input_field_mga = + hmc5883l_regval_to_input_field_mga, + .regval_to_nanoscale = hmc5883l_regval_to_nanoscale, + }, +}; + static int hmc5843_detect(struct i2c_client *client, struct i2c_board_info *info) { @@ -518,18 +640,23 @@ static int hmc5843_detect(struct i2c_client *client, return 0; } -/* Called when we have found a new HMC5843. */ -static void hmc5843_init_client(struct i2c_client *client) +/* Called when we have found a new HMC58X3 */ +static void hmc5843_init_client(struct i2c_client *client, + const struct i2c_device_id *id) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct hmc5843_data *data = iio_priv(indio_dev); + data->variant = &hmc5843_chip_info_tbl[id->driver_data]; + indio_dev->channels = data->variant->channels; + indio_dev->num_channels = data->variant->num_channels; hmc5843_set_meas_conf(client, data->meas_conf); hmc5843_set_rate(client, data->rate); hmc5843_configure(client, data->operating_mode); i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range); mutex_init(&data->lock); - pr_info("HMC5843 initialized\n"); + + pr_info("%s initialized\n", id->name); } static const struct iio_info hmc5843_info = { @@ -545,35 +672,34 @@ static int hmc5843_probe(struct i2c_client *client, struct iio_dev *indio_dev; int err = 0; - indio_dev = iio_allocate_device(sizeof(*data)); + indio_dev = iio_device_alloc(sizeof(*data)); if (indio_dev == NULL) { err = -ENOMEM; goto exit; } - data = iio_priv(indio_dev); - /* default settings at probe */ - data->meas_conf = CONF_NORMAL; - data->range = RANGE_1_0; - data->operating_mode = MODE_CONVERSION_CONTINUOUS; + /* default settings at probe */ + data = iio_priv(indio_dev); + data->meas_conf = HMC5843_MEAS_CONF_NORMAL; + data->range = HMC5843_RANGE_GAIN_DEFAULT; + data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS; i2c_set_clientdata(client, indio_dev); - - /* Initialize the HMC5843 chip */ - hmc5843_init_client(client); + hmc5843_init_client(client, id); indio_dev->info = &hmc5843_info; indio_dev->name = id->name; - indio_dev->channels = hmc5843_channels; - indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels); indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; + err = iio_device_register(indio_dev); if (err) goto exit_free2; + return 0; + exit_free2: - iio_free_device(indio_dev); + iio_device_free(indio_dev); exit: return err; } @@ -584,8 +710,8 @@ static int hmc5843_remove(struct i2c_client *client) iio_device_unregister(indio_dev); /* sleep mode to save power */ - hmc5843_configure(client, MODE_SLEEP); - iio_free_device(indio_dev); + hmc5843_configure(client, HMC5843_MODE_SLEEP); + iio_device_free(indio_dev); return 0; } @@ -593,14 +719,18 @@ static int hmc5843_remove(struct i2c_client *client) #ifdef CONFIG_PM_SLEEP static int hmc5843_suspend(struct device *dev) { - hmc5843_configure(to_i2c_client(dev), MODE_SLEEP); + hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP); return 0; } static int hmc5843_resume(struct device *dev) { - struct hmc5843_data *data = i2c_get_clientdata(to_i2c_client(dev)); - hmc5843_configure(to_i2c_client(dev), data->operating_mode); + struct i2c_client *client = to_i2c_client(dev); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct hmc5843_data *data = iio_priv(indio_dev); + + hmc5843_configure(client, data->operating_mode); + return 0; } @@ -611,7 +741,9 @@ static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume); #endif static const struct i2c_device_id hmc5843_id[] = { - { "hmc5843", 0 }, + { "hmc5843", HMC5843_ID }, + { "hmc5883", HMC5883_ID }, + { "hmc5883l", HMC5883L_ID }, { } }; MODULE_DEVICE_TABLE(i2c, hmc5843_id); @@ -630,5 +762,5 @@ static struct i2c_driver hmc5843_driver = { module_i2c_driver(hmc5843_driver); MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com"); -MODULE_DESCRIPTION("HMC5843 driver"); +MODULE_DESCRIPTION("HMC5843/5883/5883L driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 57baac6..f04ece7 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -18,8 +18,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "meter.h" #include "ade7753.h" @@ -28,7 +28,7 @@ static int ade7753_spi_write_reg_8(struct device *dev, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -46,7 +46,7 @@ static int ade7753_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -63,7 +63,7 @@ static int ade7753_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); ssize_t ret; @@ -82,7 +82,7 @@ static int ade7753_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); ssize_t ret; @@ -104,7 +104,7 @@ static int ade7753_spi_read_reg_24(struct device *dev, u32 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -416,7 +416,7 @@ static ssize_t ade7753_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7753_state *st = iio_priv(indio_dev); unsigned long val; int ret; @@ -517,7 +517,7 @@ static int __devinit ade7753_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -546,7 +546,7 @@ static int __devinit ade7753_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -564,7 +564,7 @@ static int ade7753_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; } diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 8d81c920..6cee28a 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -18,8 +18,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "meter.h" #include "ade7754.h" @@ -28,7 +28,7 @@ static int ade7754_spi_write_reg_8(struct device *dev, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -46,7 +46,7 @@ static int ade7754_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -63,7 +63,7 @@ static int ade7754_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); int ret; @@ -82,7 +82,7 @@ static int ade7754_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); int ret; @@ -104,7 +104,7 @@ static int ade7754_spi_read_reg_24(struct device *dev, u32 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -436,7 +436,7 @@ static ssize_t ade7754_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7754_state *st = iio_priv(indio_dev); unsigned long val; int ret; @@ -540,7 +540,7 @@ static int __devinit ade7754_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -568,7 +568,7 @@ static int __devinit ade7754_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; @@ -585,7 +585,7 @@ static int ade7754_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index dcb2029..96d6114 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -18,9 +18,9 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" -#include "../buffer.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include <linux/iio/buffer.h> #include "meter.h" #include "ade7758.h" @@ -29,7 +29,7 @@ int ade7758_spi_write_reg_8(struct device *dev, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -48,7 +48,7 @@ static int ade7758_spi_write_reg_16(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { @@ -77,7 +77,7 @@ static int ade7758_spi_write_reg_24(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { @@ -106,7 +106,7 @@ int ade7758_spi_read_reg_8(struct device *dev, u8 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -149,7 +149,7 @@ static int ade7758_spi_read_reg_16(struct device *dev, u16 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -195,7 +195,7 @@ static int ade7758_spi_read_reg_24(struct device *dev, u32 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7758_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -534,7 +534,7 @@ static ssize_t ade7758_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); unsigned long val; int ret; u8 reg, t; @@ -662,66 +662,217 @@ static const struct attribute_group ade7758_attribute_group = { }; static struct iio_chan_spec ade7758_channels[] = { - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), - 0, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), - 1, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), - 2, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), - 3, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 0, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), - 4, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), - 5, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), - 6, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), - 7, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), - 8, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 1, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), - 9, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, "raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), - 10, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), - 11, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), - 12, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), - 13, IIO_ST('s', 24, 32, 0), 0), - IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 2, 0, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), - 14, IIO_ST('s', 24, 32, 0), 0), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 0, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT), + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR), + .scan_index = 2, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR), + .scan_index = 3, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 0, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR), + .scan_index = 4, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE), + .scan_index = 5, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 1, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT), + .scan_index = 6, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR), + .scan_index = 7, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR), + .scan_index = 8, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 1, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR), + .scan_index = 9, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 2, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE), + .scan_index = 10, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_CURRENT, + .indexed = 1, + .channel = 2, + .extend_name = "raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT), + .scan_index = 11, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "apparent_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR), + .scan_index = 12, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "active_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR), + .scan_index = 13, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, { + .type = IIO_POWER, + .indexed = 1, + .channel = 2, + .extend_name = "reactive_raw", + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR), + .scan_index = 14, + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + }, + }, IIO_CHAN_SOFT_TIMESTAMP(15), }; @@ -734,7 +885,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) { int i, ret; struct ade7758_state *st; - struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; @@ -800,7 +951,7 @@ static int __devinit ade7758_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) + if (spi->irq) ade7758_remove_trigger(indio_dev); error_uninitialize_ring: ade7758_uninitialize_ring(indio_dev); @@ -811,7 +962,7 @@ error_free_tx: error_free_rx: kfree(st->rx); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -833,7 +984,7 @@ static int ade7758_remove(struct spi_device *spi) kfree(st->tx); kfree(st->rx); - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index c45b23b..92159f2 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -12,18 +12,17 @@ #include <linux/slab.h> #include <asm/unaligned.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "../ring_sw.h" -#include "../trigger_consumer.h" +#include <linux/iio/trigger_consumer.h> #include "ade7758.h" /** * ade7758_spi_read_burst() - read data registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: the IIO device **/ -static int ade7758_spi_read_burst(struct device *dev) +static int ade7758_spi_read_burst(struct iio_dev *indio_dev) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ade7758_state *st = iio_priv(indio_dev); int ret; @@ -68,11 +67,11 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) u32 *dat32 = (u32 *)dat64; if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) - if (ade7758_spi_read_burst(&indio_dev->dev) >= 0) + if (ade7758_spi_read_burst(indio_dev) >= 0) *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF; /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); @@ -92,29 +91,19 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) static int ade7758_ring_preenable(struct iio_dev *indio_dev) { struct ade7758_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - size_t d_size; unsigned channel; + int ret; if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) return -EINVAL; + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + channel = find_first_bit(indio_dev->active_scan_mask, indio_dev->masklength); - d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8; - - if (ring->scan_timestamp) { - d_size += sizeof(s64); - - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - - if (indio_dev->buffer->access->set_bytes_per_datum) - indio_dev->buffer->access-> - set_bytes_per_datum(indio_dev->buffer, d_size); - ade7758_write_waveform_type(&indio_dev->dev, st->ade7758_ring_channels[channel].address); diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c index b6569c7..f9c6a34 100644 --- a/drivers/staging/iio/meter/ade7758_trigger.c +++ b/drivers/staging/iio/meter/ade7758_trigger.c @@ -11,8 +11,8 @@ #include <linux/spi/spi.h> #include <linux/export.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> #include "ade7758.h" /** @@ -63,7 +63,7 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev) struct ade7758_state *st = iio_priv(indio_dev); int ret; - st->trig = iio_allocate_trigger("%s-dev%d", + st->trig = iio_trigger_alloc("%s-dev%d", spi_get_device_id(st->us)->name, indio_dev->id); if (st->trig == NULL) { @@ -94,7 +94,7 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev) error_free_irq: free_irq(st->us->irq, st->trig); error_free_trig: - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); error_ret: return ret; } @@ -105,5 +105,5 @@ void ade7758_remove_trigger(struct iio_dev *indio_dev) iio_trigger_unregister(st->trig); free_irq(st->us->irq, st->trig); - iio_free_trigger(st->trig); + iio_trigger_free(st->trig); } diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 0beab47..b3f7e0fa9 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -18,8 +18,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "meter.h" #include "ade7759.h" @@ -28,7 +28,7 @@ static int ade7759_spi_write_reg_8(struct device *dev, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -46,7 +46,7 @@ static int ade7759_spi_write_reg_16(struct device *dev, u16 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -63,7 +63,7 @@ static int ade7759_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); int ret; @@ -82,7 +82,7 @@ static int ade7759_spi_read_reg_16(struct device *dev, u8 reg_address, u16 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); int ret; @@ -104,7 +104,7 @@ static int ade7759_spi_read_reg_40(struct device *dev, u64 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -376,7 +376,7 @@ static ssize_t ade7759_write_frequency(struct device *dev, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7759_state *st = iio_priv(indio_dev); unsigned long val; int ret; @@ -463,7 +463,7 @@ static int __devinit ade7759_probe(struct spi_device *spi) struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -491,7 +491,7 @@ static int __devinit ade7759_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -507,7 +507,7 @@ static int ade7759_remove(struct spi_device *spi) if (ret) goto err_ret; - iio_free_device(indio_dev); + iio_device_free(indio_dev); err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 1e1faa0..0609046 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -12,7 +12,7 @@ #include <linux/slab.h> #include <linux/module.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "ade7854.h" static int ade7854_i2c_write_reg_8(struct device *dev, @@ -20,7 +20,7 @@ static int ade7854_i2c_write_reg_8(struct device *dev, u8 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -39,7 +39,7 @@ static int ade7854_i2c_write_reg_16(struct device *dev, u16 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -59,7 +59,7 @@ static int ade7854_i2c_write_reg_24(struct device *dev, u32 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -80,7 +80,7 @@ static int ade7854_i2c_write_reg_32(struct device *dev, u32 value) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -101,7 +101,7 @@ static int ade7854_i2c_read_reg_8(struct device *dev, u16 reg_address, u8 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -127,7 +127,7 @@ static int ade7854_i2c_read_reg_16(struct device *dev, u16 reg_address, u16 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -153,7 +153,7 @@ static int ade7854_i2c_read_reg_24(struct device *dev, u16 reg_address, u32 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -179,7 +179,7 @@ static int ade7854_i2c_read_reg_32(struct device *dev, u16 reg_address, u32 *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -208,7 +208,7 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, struct ade7854_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); @@ -226,7 +226,7 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, ret = ade7854_probe(indio_dev, &client->dev); if (ret) - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 8112186..9fb2f8b 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -12,7 +12,7 @@ #include <linux/slab.h> #include <linux/module.h> -#include "../iio.h" +#include <linux/iio/iio.h> #include "ade7854.h" static int ade7854_spi_write_reg_8(struct device *dev, @@ -21,7 +21,7 @@ static int ade7854_spi_write_reg_8(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, @@ -49,7 +49,7 @@ static int ade7854_spi_write_reg_16(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, @@ -78,7 +78,7 @@ static int ade7854_spi_write_reg_24(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, @@ -108,7 +108,7 @@ static int ade7854_spi_write_reg_32(struct device *dev, { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, @@ -138,7 +138,7 @@ static int ade7854_spi_read_reg_8(struct device *dev, u8 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -180,7 +180,7 @@ static int ade7854_spi_read_reg_16(struct device *dev, u16 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -221,7 +221,7 @@ static int ade7854_spi_read_reg_24(struct device *dev, u32 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -263,7 +263,7 @@ static int ade7854_spi_read_reg_32(struct device *dev, u32 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -306,7 +306,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) struct ade7854_state *st; struct iio_dev *indio_dev; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); @@ -325,7 +325,7 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) ret = ade7854_probe(indio_dev, &spi->dev); if (ret) - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 49c01c5..c642da8 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -17,8 +17,8 @@ #include <linux/list.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "meter.h" #include "ade7854.h" @@ -28,7 +28,7 @@ static ssize_t ade7854_read_8bit(struct device *dev, { int ret; u8 val = 0; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -45,7 +45,7 @@ static ssize_t ade7854_read_16bit(struct device *dev, { int ret; u16 val = 0; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -62,7 +62,7 @@ static ssize_t ade7854_read_24bit(struct device *dev, { int ret; u32 val; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); @@ -80,7 +80,7 @@ static ssize_t ade7854_read_32bit(struct device *dev, int ret; u32 val = 0; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); ret = st->read_reg_32(dev, this_attr->address, &val); @@ -96,7 +96,7 @@ static ssize_t ade7854_write_8bit(struct device *dev, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -117,7 +117,7 @@ static ssize_t ade7854_write_16bit(struct device *dev, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -138,7 +138,7 @@ static ssize_t ade7854_write_24bit(struct device *dev, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -159,7 +159,7 @@ static ssize_t ade7854_write_32bit(struct device *dev, size_t len) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -176,7 +176,7 @@ error_ret: static int ade7854_reset(struct device *dev) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); u16 val; @@ -425,7 +425,7 @@ static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit, static int ade7854_set_irq(struct device *dev, bool enable) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ade7854_state *st = iio_priv(indio_dev); int ret; @@ -581,7 +581,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev) error_unreg_dev: iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); return ret; } @@ -590,7 +590,7 @@ EXPORT_SYMBOL(ade7854_probe); int ade7854_remove(struct iio_dev *indio_dev) { iio_device_unregister(indio_dev); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/meter/meter.h b/drivers/staging/iio/meter/meter.h index 6a3db14..23e1b5f4 100644 --- a/drivers/staging/iio/meter/meter.h +++ b/drivers/staging/iio/meter/meter.h @@ -1,4 +1,4 @@ -#include "../sysfs.h" +#include <linux/iio/sysfs.h> /* metering ic types of attribute */ diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index d8ce854..8b71eb0 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -19,8 +19,8 @@ #include <linux/gpio.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #define DRV_NAME "ad2s1200" @@ -85,10 +85,12 @@ static const struct iio_chan_spec ad2s1200_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; @@ -110,7 +112,7 @@ static int __devinit ad2s1200_probe(struct spi_device *spi) DRV_NAME, pins[pn]); goto error_ret; } - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -140,7 +142,7 @@ static int __devinit ad2s1200_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: for (--pn; pn >= 0; pn--) gpio_free(pins[pn]); @@ -150,7 +152,7 @@ error_ret: static int __devexit ad2s1200_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index c439fcf..f313859 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -18,8 +18,8 @@ #include <linux/gpio.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> #include "ad2s1210.h" #define DRV_NAME "ad2s1210" @@ -200,7 +200,7 @@ static ssize_t ad2s1210_store_softreset(struct device *dev, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); int ret; mutex_lock(&st->lock); @@ -214,7 +214,7 @@ static ssize_t ad2s1210_show_fclkin(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); return sprintf(buf, "%d\n", st->fclkin); } @@ -223,7 +223,7 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); unsigned long fclkin; int ret; @@ -252,7 +252,7 @@ static ssize_t ad2s1210_show_fexcit(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); return sprintf(buf, "%d\n", st->fexcit); } @@ -260,7 +260,7 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); unsigned long fexcit; int ret; @@ -287,7 +287,7 @@ static ssize_t ad2s1210_show_control(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); int ret; mutex_lock(&st->lock); ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); @@ -299,7 +299,7 @@ static ssize_t ad2s1210_store_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); unsigned long udata; unsigned char data; int ret; @@ -345,7 +345,7 @@ error_ret: static ssize_t ad2s1210_show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); return sprintf(buf, "%d\n", st->resolution); } @@ -353,7 +353,7 @@ static ssize_t ad2s1210_store_resolution(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); unsigned char data; unsigned long udata; int ret; @@ -403,7 +403,7 @@ error_ret: static ssize_t ad2s1210_show_fault(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); int ret; mutex_lock(&st->lock); @@ -418,7 +418,7 @@ static ssize_t ad2s1210_clear_fault(struct device *dev, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); int ret; mutex_lock(&st->lock); @@ -441,7 +441,7 @@ static ssize_t ad2s1210_show_reg(struct device *dev, struct device_attribute *attr, char *buf) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); struct iio_dev_attr *iattr = to_iio_dev_attr(attr); int ret; @@ -455,7 +455,7 @@ static ssize_t ad2s1210_show_reg(struct device *dev, static ssize_t ad2s1210_store_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev)); unsigned long data; int ret; struct iio_dev_attr *iattr = to_iio_dev_attr(attr); @@ -580,10 +580,12 @@ static struct iio_chan_spec ad2s1210_channels[] = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }, { .type = IIO_ANGL_VEL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, } }; @@ -688,7 +690,7 @@ static int __devinit ad2s1210_probe(struct spi_device *spi) if (spi->dev.platform_data == NULL) return -EINVAL; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -729,7 +731,7 @@ static int __devinit ad2s1210_probe(struct spi_device *spi) error_free_gpios: ad2s1210_free_gpios(st); error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -740,7 +742,7 @@ static int __devexit ad2s1210_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad2s1210_free_gpios(iio_priv(indio_dev)); - iio_free_device(indio_dev); + iio_device_free(indio_dev); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 2a86f58..a805722 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -16,8 +16,8 @@ #include <linux/sysfs.h> #include <linux/module.h> -#include "../iio.h" -#include "../sysfs.h" +#include <linux/iio/iio.h> +#include <linux/iio/sysfs.h> struct ad2s90_state { struct mutex lock; @@ -55,6 +55,7 @@ static const struct iio_chan_spec ad2s90_chan = { .type = IIO_ANGL, .indexed = 1, .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, }; static int __devinit ad2s90_probe(struct spi_device *spi) @@ -63,7 +64,7 @@ static int __devinit ad2s90_probe(struct spi_device *spi) struct ad2s90_state *st; int ret = 0; - indio_dev = iio_allocate_device(sizeof(*st)); + indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; @@ -92,7 +93,7 @@ static int __devinit ad2s90_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(indio_dev); + iio_device_free(indio_dev); error_ret: return ret; } @@ -100,7 +101,7 @@ error_ret: static int __devexit ad2s90_remove(struct spi_device *spi) { iio_device_unregister(spi_get_drvdata(spi)); - iio_free_device(spi_get_drvdata(spi)); + iio_device_free(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index b9945ec..9358c6c 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -15,7 +15,7 @@ #include <linux/sched.h> #include <linux/poll.h> #include "ring_sw.h" -#include "trigger.h" +#include <linux/iio/trigger.h> /** * struct iio_sw_ring_buffer - software ring buffer diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h index 7556e21..a5857aa 100644 --- a/drivers/staging/iio/ring_sw.h +++ b/drivers/staging/iio/ring_sw.h @@ -23,7 +23,7 @@ #ifndef _IIO_RING_SW_H_ #define _IIO_RING_SW_H_ -#include "buffer.h" +#include <linux/iio/buffer.h> struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev); void iio_sw_rb_free(struct iio_buffer *ring); diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h deleted file mode 100644 index bfedb73..0000000 --- a/drivers/staging/iio/sysfs.h +++ /dev/null @@ -1,117 +0,0 @@ -/* The industrial I/O core - * - *Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * General attributes - */ - -#ifndef _INDUSTRIAL_IO_SYSFS_H_ -#define _INDUSTRIAL_IO_SYSFS_H_ - -struct iio_chan_spec; - -/** - * struct iio_dev_attr - iio specific device attribute - * @dev_attr: underlying device attribute - * @address: associated register address - * @l: list head for maintaining list of dynamically created attrs. - */ -struct iio_dev_attr { - struct device_attribute dev_attr; - u64 address; - struct list_head l; - struct iio_chan_spec const *c; -}; - -#define to_iio_dev_attr(_dev_attr) \ - container_of(_dev_attr, struct iio_dev_attr, dev_attr) - -ssize_t iio_read_const_attr(struct device *dev, - struct device_attribute *attr, - char *len); - -/** - * struct iio_const_attr - constant device specific attribute - * often used for things like available modes - * @string: attribute string - * @dev_attr: underlying device attribute - */ -struct iio_const_attr { - const char *string; - struct device_attribute dev_attr; -}; - -#define to_iio_const_attr(_dev_attr) \ - container_of(_dev_attr, struct iio_const_attr, dev_attr) - -/* Some attributes will be hard coded (device dependent) and not require an - address, in these cases pass a negative */ -#define IIO_ATTR(_name, _mode, _show, _store, _addr) \ - { .dev_attr = __ATTR(_name, _mode, _show, _store), \ - .address = _addr } - -#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \ - struct iio_dev_attr iio_dev_attr_##_name \ - = IIO_ATTR(_name, _mode, _show, _store, _addr) - -#define IIO_DEVICE_ATTR_NAMED(_vname, _name, _mode, _show, _store, _addr) \ - struct iio_dev_attr iio_dev_attr_##_vname \ - = IIO_ATTR(_name, _mode, _show, _store, _addr) - -#define IIO_CONST_ATTR(_name, _string) \ - struct iio_const_attr iio_const_attr_##_name \ - = { .string = _string, \ - .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} - -#define IIO_CONST_ATTR_NAMED(_vname, _name, _string) \ - struct iio_const_attr iio_const_attr_##_vname \ - = { .string = _string, \ - .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} - -/* Generic attributes of onetype or another */ -/** - * IIO_DEV_ATTR_RESET: resets the device - **/ -#define IIO_DEV_ATTR_RESET(_store) \ - IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) - -/** - * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency - * @_mode: sysfs file mode/permissions - * @_show: output method for the attribute - * @_store: input method for the attribute - **/ -#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store) \ - IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0) - -/** - * IIO_DEV_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies - * @_show: output method for the attribute - * - * May be mode dependent on some devices - **/ -#define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ - IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) -/** - * IIO_CONST_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies - * @_string: frequency string for the attribute - * - * Constant version - **/ -#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ - IIO_CONST_ATTR(sampling_frequency_available, _string) - -#define IIO_DEV_ATTR_TEMP_RAW(_show) \ - IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0) - -#define IIO_CONST_ATTR_TEMP_OFFSET(_string) \ - IIO_CONST_ATTR(in_temp_offset, _string) - -#define IIO_CONST_ATTR_TEMP_SCALE(_string) \ - IIO_CONST_ATTR(in_temp_scale, _string) - -#endif /* _INDUSTRIAL_IO_SYSFS_H_ */ diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h deleted file mode 100644 index 1cfca23..0000000 --- a/drivers/staging/iio/trigger.h +++ /dev/null @@ -1,119 +0,0 @@ -/* The industrial I/O core, trigger handling functions - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include <linux/irq.h> -#include <linux/module.h> - -#ifndef _IIO_TRIGGER_H_ -#define _IIO_TRIGGER_H_ - -struct iio_subirq { - bool enabled; -}; - -/** - * struct iio_trigger_ops - operations structure for an iio_trigger. - * @owner: used to monitor usage count of the trigger. - * @set_trigger_state: switch on/off the trigger on demand - * @try_reenable: function to reenable the trigger when the - * use count is zero (may be NULL) - * @validate_device: function to validate the device when the - * current trigger gets changed. - * - * This is typically static const within a driver and shared by - * instances of a given device. - **/ -struct iio_trigger_ops { - struct module *owner; - int (*set_trigger_state)(struct iio_trigger *trig, bool state); - int (*try_reenable)(struct iio_trigger *trig); - int (*validate_device)(struct iio_trigger *trig, - struct iio_dev *indio_dev); -}; - - -/** - * struct iio_trigger - industrial I/O trigger device - * - * @id: [INTERN] unique id number - * @name: [DRIVER] unique name - * @dev: [DRIVER] associated device (if relevant) - * @private_data: [DRIVER] device specific data - * @list: [INTERN] used in maintenance of global trigger list - * @alloc_list: [DRIVER] used for driver specific trigger list - * @use_count: use count for the trigger - * @subirq_chip: [INTERN] associate 'virtual' irq chip. - * @subirq_base: [INTERN] base number for irqs provided by trigger. - * @subirqs: [INTERN] information about the 'child' irqs. - * @pool: [INTERN] bitmap of irqs currently in use. - * @pool_lock: [INTERN] protection of the irq pool. - **/ -struct iio_trigger { - const struct iio_trigger_ops *ops; - int id; - const char *name; - struct device dev; - - void *private_data; - struct list_head list; - struct list_head alloc_list; - int use_count; - - struct irq_chip subirq_chip; - int subirq_base; - - struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER]; - unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)]; - struct mutex pool_lock; -}; - - -static inline struct iio_trigger *to_iio_trigger(struct device *d) -{ - return container_of(d, struct iio_trigger, dev); -}; - -static inline void iio_put_trigger(struct iio_trigger *trig) -{ - module_put(trig->ops->owner); - put_device(&trig->dev); -}; - -static inline void iio_get_trigger(struct iio_trigger *trig) -{ - get_device(&trig->dev); - __module_get(trig->ops->owner); -}; - -/** - * iio_trigger_register() - register a trigger with the IIO core - * @trig_info: trigger to be registered - **/ -int iio_trigger_register(struct iio_trigger *trig_info); - -/** - * iio_trigger_unregister() - unregister a trigger from the core - * @trig_info: trigger to be unregistered - **/ -void iio_trigger_unregister(struct iio_trigger *trig_info); - -/** - * iio_trigger_poll() - called on a trigger occurring - * @trig: trigger which occurred - * - * Typically called in relevant hardware interrupt handler. - **/ -void iio_trigger_poll(struct iio_trigger *trig, s64 time); -void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); - -irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); - -__printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); -void iio_free_trigger(struct iio_trigger *trig); - -#endif /* _IIO_TRIGGER_H_ */ diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 665653d..f85734d 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -15,8 +15,8 @@ #include <asm/gptimers.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> struct bfin_timer { unsigned short id, bit; @@ -172,7 +172,7 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; - st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num); + st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num); if (!st->trig) { ret = -ENOMEM; goto out1; @@ -203,7 +203,7 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) out4: iio_trigger_unregister(st->trig); out2: - iio_put_trigger(st->trig); + iio_trigger_put(st->trig); out1: kfree(st); out: @@ -217,7 +217,7 @@ static int __devexit iio_bfin_tmr_trigger_remove(struct platform_device *pdev) disable_gptimers(st->t->bit); free_irq(st->irq, st); iio_trigger_unregister(st->trig); - iio_put_trigger(st->trig); + iio_trigger_put(st->trig); kfree(st); return 0; diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index a346594..90b2684 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -22,8 +22,8 @@ #include <linux/gpio.h> #include <linux/slab.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> static LIST_HEAD(iio_gpio_trigger_list); static DEFINE_MUTEX(iio_gpio_trigger_list_lock); @@ -72,7 +72,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) for (irq = irq_res->start; irq <= irq_res->end; irq++) { - trig = iio_allocate_trigger("irqtrig%d", irq); + trig = iio_trigger_alloc("irqtrig%d", irq); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -114,7 +114,7 @@ error_release_irq: error_free_trig_info: kfree(trig_info); error_put_trigger: - iio_put_trigger(trig); + iio_trigger_put(trig); error_free_completed_registrations: /* The rest should have been added to the iio_gpio_trigger_list */ list_for_each_entry_safe(trig, @@ -144,7 +144,7 @@ static int iio_gpio_trigger_remove(struct platform_device *pdev) iio_trigger_unregister(trig); free_irq(trig_info->irq, trig); kfree(trig_info); - iio_put_trigger(trig); + iio_trigger_put(trig); } mutex_unlock(&iio_gpio_trigger_list_lock); diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index a80cf67..9f2d055 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -16,8 +16,8 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/rtc.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> static LIST_HEAD(iio_prtc_trigger_list); static DEFINE_MUTEX(iio_prtc_trigger_list_lock); @@ -112,7 +112,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) for (i = 0;; i++) { if (pdata[i] == NULL) break; - trig = iio_allocate_trigger("periodic%s", pdata[i]); + trig = iio_trigger_alloc("periodic%s", pdata[i]); if (!trig) { ret = -ENOMEM; goto error_free_completed_registrations; @@ -152,7 +152,7 @@ error_free_trig_info: kfree(trig_info); error_put_trigger_and_remove_from_list: list_del(&trig->alloc_list); - iio_put_trigger(trig); + iio_trigger_put(trig); error_free_completed_registrations: list_for_each_entry_safe(trig, trig2, diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 174dc65..552763b 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -11,8 +11,8 @@ #include <linux/slab.h> #include <linux/list.h> -#include "../iio.h" -#include "../trigger.h" +#include <linux/iio/iio.h> +#include <linux/iio/trigger.h> struct iio_sysfs_trig { struct iio_trigger *trig; @@ -139,7 +139,7 @@ static int iio_sysfs_trigger_probe(int id) goto out1; } t->id = id; - t->trig = iio_allocate_trigger("sysfstrig%d", id); + t->trig = iio_trigger_alloc("sysfstrig%d", id); if (!t->trig) { ret = -ENOMEM; goto free_t; @@ -158,7 +158,7 @@ static int iio_sysfs_trigger_probe(int id) return 0; out2: - iio_put_trigger(t->trig); + iio_trigger_put(t->trig); free_t: kfree(t); out1: @@ -182,7 +182,7 @@ static int iio_sysfs_trigger_remove(int id) } iio_trigger_unregister(t->trig); - iio_free_trigger(t->trig); + iio_trigger_free(t->trig); list_del(&t->l); kfree(t); diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h deleted file mode 100644 index 60d64b3..0000000 --- a/drivers/staging/iio/trigger_consumer.h +++ /dev/null @@ -1,52 +0,0 @@ -/* The industrial I/O core, trigger consumer functions - * - * Copyright (c) 2008-2011 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -/** - * struct iio_poll_func - poll function pair - * - * @indio_dev: data specific to device (passed into poll func) - * @h: the function that is actually run on trigger - * @thread: threaded interrupt part - * @type: the type of interrupt (basically if oneshot) - * @name: name used to identify the trigger consumer. - * @irq: the corresponding irq as allocated from the - * trigger pool - * @timestamp: some devices need a timestamp grabbed as soon - * as possible after the trigger - hence handler - * passes it via here. - **/ -struct iio_poll_func { - struct iio_dev *indio_dev; - irqreturn_t (*h)(int irq, void *p); - irqreturn_t (*thread)(int irq, void *p); - int type; - char *name; - int irq; - s64 timestamp; -}; - - -struct iio_poll_func -*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), - irqreturn_t (*thread)(int irq, void *p), - int type, - struct iio_dev *indio_dev, - const char *fmt, - ...); -void iio_dealloc_pollfunc(struct iio_poll_func *pf); -irqreturn_t iio_pollfunc_store_time(int irq, void *p); - -void iio_trigger_notify_done(struct iio_trigger *trig); - -/* - * Two functions for common case where all that happens is a pollfunc - * is attached and detached from a trigger - */ -int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); -int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/types.h b/drivers/staging/iio/types.h deleted file mode 100644 index 0c32136..0000000 --- a/drivers/staging/iio/types.h +++ /dev/null @@ -1,53 +0,0 @@ -/* industrial I/O data types needed both in and out of kernel - * - * Copyright (c) 2008 Jonathan Cameron - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _IIO_TYPES_H_ -#define _IIO_TYPES_H_ - -enum iio_chan_type { - /* real channel types */ - IIO_VOLTAGE, - IIO_CURRENT, - IIO_POWER, - IIO_ACCEL, - IIO_ANGL_VEL, - IIO_MAGN, - IIO_LIGHT, - IIO_INTENSITY, - IIO_PROXIMITY, - IIO_TEMP, - IIO_INCLI, - IIO_ROT, - IIO_ANGL, - IIO_TIMESTAMP, - IIO_CAPACITANCE, -}; - -enum iio_modifier { - IIO_NO_MOD, - IIO_MOD_X, - IIO_MOD_Y, - IIO_MOD_Z, - IIO_MOD_X_AND_Y, - IIO_MOD_X_AND_Z, - IIO_MOD_Y_AND_Z, - IIO_MOD_X_AND_Y_AND_Z, - IIO_MOD_X_OR_Y, - IIO_MOD_X_OR_Z, - IIO_MOD_Y_OR_Z, - IIO_MOD_X_OR_Y_OR_Z, - IIO_MOD_LIGHT_BOTH, - IIO_MOD_LIGHT_IR, -}; - -#define IIO_VAL_INT 1 -#define IIO_VAL_INT_PLUS_MICRO 2 -#define IIO_VAL_INT_PLUS_NANO 3 - -#endif /* _IIO_TYPES_H_ */ diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig new file mode 100644 index 0000000..af32178 --- /dev/null +++ b/drivers/staging/ipack/Kconfig @@ -0,0 +1,20 @@ +# +# IPACK configuration. +# + +menuconfig IPACK_BUS + tristate "IndustryPack bus support" + ---help--- + If you say Y here you get support for the IndustryPack Framework + for drivers for many types of boards that support this industrial + bus. The IndustryPack Framework is a virtual bus allowing to + communicate between carrier and mezzanine cards connected through + this bus. + +if IPACK_BUS + +source "drivers/staging/ipack/bridges/Kconfig" + +source "drivers/staging/ipack/devices/Kconfig" + +endif # IPACK diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile new file mode 100644 index 0000000..85ff223 --- /dev/null +++ b/drivers/staging/ipack/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the IPACK bridge device drivers. +# +obj-$(CONFIG_IPACK_BUS) += ipack.o +obj-y += devices/ +obj-y += bridges/ diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO new file mode 100644 index 0000000..3a45a53 --- /dev/null +++ b/drivers/staging/ipack/TODO @@ -0,0 +1,46 @@ + TODO + ==== +Introduction +============ + +These drivers add support for IndustryPack devices: carrier and mezzanine +boards. + +The ipack driver is just an abstraction of the bus providing the common +operations between the two kind of boards. + +TODO +==== + +TPCI-200 +-------- + +* It receives the name of the mezzanine plugged in each slot by SYSFS. + No autodetection supported yet, because the mezzanine driver could not be + loaded at the time that the tpci200 driver loads. + +* It has a linked list with the tpci200 devices it is managing. Get rid of it + and use driver_for_each_device() instead. + +IP-OCTAL +-------- + +* It has a linked list which saves the devices it is currently + managing. It should use the driver_for_each_device() function. It is not there + due to the impossibility of using container_of macro to recover the + corresponding "struct ipoctal" because the attribute "struct ipack_device" is + a pointer. This code should be refactored. + +Ipack +----- + +* The structures and API exported can be improved a lot. For example, the + way to unregistering mezzanine devices, doing the mezzanine driver a call to + remove_device() to notify the carrier driver, or the opposite with the call to + the ipack_driver_ops' remove() function could be improved. + + +Contact +======= + +Contact: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
\ No newline at end of file diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig new file mode 100644 index 0000000..97c837e --- /dev/null +++ b/drivers/staging/ipack/bridges/Kconfig @@ -0,0 +1,8 @@ +config BOARD_TPCI200 + tristate "TEWS TPCI-200 support for IndustryPack bus" + depends on IPACK_BUS + depends on PCI + help + This driver supports the TEWS TPCI200 device for the IndustryPack bus. + default n + diff --git a/drivers/staging/ipack/bridges/Makefile b/drivers/staging/ipack/bridges/Makefile new file mode 100644 index 0000000..d8b7645 --- /dev/null +++ b/drivers/staging/ipack/bridges/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c new file mode 100644 index 0000000..ad28707 --- /dev/null +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -0,0 +1,1141 @@ +/** + * tpci200.c + * + * driver for the TEWS TPCI-200 device + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include "tpci200.h" + +static struct ipack_bus_ops tpci200_bus_ops; + +/* TPCI200 controls registers */ +static int control_reg[] = { + TPCI200_CONTROL_A_REG, + TPCI200_CONTROL_B_REG, + TPCI200_CONTROL_C_REG, + TPCI200_CONTROL_D_REG +}; + +/* Linked list to save the registered devices */ +static LIST_HEAD(tpci200_list); + +static int tpci200_slot_unregister(struct ipack_device *dev); + +static struct tpci200_board *check_slot(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + int found = 0; + + if (dev == NULL) { + pr_info("Slot doesn't exist.\n"); + return NULL; + } + + list_for_each_entry(tpci200, &tpci200_list, list) { + if (tpci200->number == dev->bus_nr) { + found = 1; + break; + } + } + + if (!found) { + pr_err("Carrier not found\n"); + return NULL; + } + + if (dev->slot >= TPCI200_NB_SLOT) { + pr_info("Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", + dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1); + return NULL; + } + + BUG_ON(tpci200->slots == NULL); + if (tpci200->slots[dev->slot].dev == NULL) { + pr_info("Slot [%d:%d] is not registered !\n", dev->bus_nr, + dev->slot); + return NULL; + } + + return tpci200; +} + +static inline unsigned char __tpci200_read8(void __iomem *address, + unsigned long offset) +{ + return ioread8(address + (offset^1)); +} + +static inline unsigned short __tpci200_read16(void __iomem *address, + unsigned long offset) +{ + return ioread16(address + offset); +} + +static inline unsigned int __tpci200_read32(void __iomem *address, + unsigned long offset) +{ + return swahw32(ioread32(address + offset)); +} + +static inline void __tpci200_write8(unsigned char value, + void __iomem *address, unsigned long offset) +{ + iowrite8(value, address+(offset^1)); +} + +static inline void __tpci200_write16(unsigned short value, + void __iomem *address, + unsigned long offset) +{ + iowrite16(value, address+offset); +} + +static inline void __tpci200_write32(unsigned int value, + void __iomem *address, + unsigned long offset) +{ + iowrite32(swahw32(value), address+offset); +} + +static struct ipack_addr_space *get_slot_address_space(struct ipack_device *dev, + int space) +{ + struct ipack_addr_space *addr; + + switch (space) { + case IPACK_IO_SPACE: + addr = &dev->io_space; + break; + case IPACK_ID_SPACE: + addr = &dev->id_space; + break; + case IPACK_MEM_SPACE: + addr = &dev->mem_space; + break; + default: + pr_err("Slot [%d:%d] space number %d doesn't exist !\n", + dev->bus_nr, dev->slot, space); + return NULL; + break; + } + + if ((addr->size == 0) || (addr->address == NULL)) { + pr_err("Error, slot space not mapped !\n"); + return NULL; + } + + return addr; +} + +static int tpci200_read8(struct ipack_device *dev, int space, + unsigned long offset, unsigned char *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if (offset >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + *value = __tpci200_read8(addr->address, offset); + + return 0; +} + +static int tpci200_read16(struct ipack_device *dev, int space, + unsigned long offset, unsigned short *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+2) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + *value = __tpci200_read16(addr->address, offset); + + return 0; +} + +static int tpci200_read32(struct ipack_device *dev, int space, + unsigned long offset, unsigned int *value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+4) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + *value = __tpci200_read32(addr->address, offset); + + return 0; +} + +static int tpci200_write8(struct ipack_device *dev, int space, + unsigned long offset, unsigned char value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if (offset >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write8(value, addr->address, offset); + + return 0; +} + +static int tpci200_write16(struct ipack_device *dev, int space, + unsigned long offset, unsigned short value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+2) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write16(value, addr->address, offset); + + return 0; +} + +static int tpci200_write32(struct ipack_device *dev, int space, + unsigned long offset, unsigned int value) +{ + struct ipack_addr_space *addr; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + addr = get_slot_address_space(dev, space); + if (addr == NULL) + return -EINVAL; + + if ((offset+4) >= addr->size) { + pr_err("Error, slot space offset error !\n"); + return -EFAULT; + } + + __tpci200_write32(value, addr->address, offset); + + return 0; +} + +static void tpci200_unregister(struct tpci200_board *tpci200) +{ + int i; + + free_irq(tpci200->info->pdev->irq, (void *) tpci200); + + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); + pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space); + pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space); + + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + + pci_disable_device(tpci200->info->pdev); + pci_dev_put(tpci200->info->pdev); + + kfree(tpci200->info); + + for (i = 0; i < TPCI200_NB_SLOT; i++) { + tpci200->slots[i].io_phys.address = NULL; + tpci200->slots[i].io_phys.size = 0; + tpci200->slots[i].id_phys.address = NULL; + tpci200->slots[i].id_phys.size = 0; + tpci200->slots[i].mem_phys.address = NULL; + tpci200->slots[i].mem_phys.size = 0; + } +} + +static irqreturn_t tpci200_interrupt(int irq, void *dev_id) +{ + struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; + int i; + unsigned long flags; + unsigned short status_reg, reg_value; + unsigned short unhandled_ints = 0; + irqreturn_t ret = IRQ_NONE; + + spin_lock_irqsave(&tpci200->info->access_lock, flags); + + /* Read status register */ + status_reg = readw(tpci200->info->interface_regs + + TPCI200_STATUS_REG); + + if (status_reg & TPCI200_SLOT_INT_MASK) { + unhandled_ints = status_reg & TPCI200_SLOT_INT_MASK; + /* callback to the IRQ handler for the corresponding slot */ + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if ((tpci200->slots[i].irq != NULL) && + (status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i)))) { + + ret = tpci200->slots[i].irq->handler(tpci200->slots[i].irq->arg); + + /* Dummy reads */ + readw(tpci200->slots[i].dev->io_space.address + + 0xC0); + readw(tpci200->slots[i].dev->io_space.address + + 0xC2); + + unhandled_ints &= ~(((TPCI200_A_INT0 | TPCI200_A_INT1) << (2*i))); + } + } + } + /* Interrupt not handled are disabled */ + if (unhandled_ints) { + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (unhandled_ints & ((TPCI200_INT0_EN | TPCI200_INT1_EN) << (2*i))) { + pr_info("No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", + tpci200->number, i); + reg_value = readw( + tpci200->info->interface_regs + + control_reg[i]); + reg_value &= + ~(TPCI200_INT0_EN | TPCI200_INT1_EN); + writew(reg_value, + (tpci200->info->interface_regs + + control_reg[i])); + } + } + } + + spin_unlock_irqrestore(&tpci200->info->access_lock, flags); + return ret; +} + +#ifdef CONFIG_SYSFS + +static struct ipack_device *tpci200_slot_register(unsigned int tpci200_number, + unsigned int slot_position) +{ + int found = 0; + struct ipack_device *dev; + struct tpci200_board *tpci200; + + list_for_each_entry(tpci200, &tpci200_list, list) { + if (tpci200->number == tpci200_number) { + found = 1; + break; + } + } + + if (!found) { + pr_err("carrier board not found for the device\n"); + return NULL; + } + + if (slot_position >= TPCI200_NB_SLOT) { + pr_info("Slot [%d:%d] doesn't exist!\n", tpci200_number, + slot_position); + return NULL; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) + return NULL; + + if (tpci200->slots[slot_position].dev != NULL) { + pr_err("Slot [%d:%d] already installed !\n", tpci200_number, + slot_position); + goto err_unlock; + } + + /* + * Give the same IRQ number as the slot number. + * The TPCI200 has assigned his own two IRQ by PCI bus driver + */ + dev = ipack_device_register(tpci200->info->ipack_bus, + slot_position, slot_position); + if (dev == NULL) { + pr_info("Slot [%d:%d] Unable to register an ipack device\n", + tpci200_number, slot_position); + goto err_unlock; + } + + tpci200->slots[slot_position].dev = dev; + mutex_unlock(&tpci200->mutex); + return dev; + +err_unlock: + mutex_unlock(&tpci200->mutex); + return NULL; +} + +static ssize_t tpci200_store_board(struct device *pdev, const char *buf, + size_t count, int slot) +{ + struct tpci200_board *card = dev_get_drvdata(pdev); + struct ipack_device *dev = card->slots[slot].dev; + + if (dev != NULL) + return -EBUSY; + + dev = tpci200_slot_register(card->number, slot); + if (dev == NULL) + return -ENODEV; + + return count; +} + +static ssize_t tpci200_show_board(struct device *pdev, char *buf, int slot) +{ + struct tpci200_board *card = dev_get_drvdata(pdev); + struct ipack_device *dev = card->slots[slot].dev; + + if (dev != NULL) + return snprintf(buf, PAGE_SIZE, "%s\n", dev_name(&dev->dev)); + else + return snprintf(buf, PAGE_SIZE, "none\n"); +} + +static ssize_t tpci200_show_description(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, + "TEWS tpci200 carrier PCI for Industry-pack mezzanines.\n"); +} + +static ssize_t tpci200_show_board_slot0(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 0); +} + +static ssize_t tpci200_store_board_slot0(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 0); +} + +static ssize_t tpci200_show_board_slot1(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 1); +} + +static ssize_t tpci200_store_board_slot1(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 1); +} + +static ssize_t tpci200_show_board_slot2(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 2); +} + +static ssize_t tpci200_store_board_slot2(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 2); +} + + +static ssize_t tpci200_show_board_slot3(struct device *pdev, + struct device_attribute *attr, + char *buf) +{ + return tpci200_show_board(pdev, buf, 3); +} + +static ssize_t tpci200_store_board_slot3(struct device *pdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + return tpci200_store_board(pdev, buf, count, 3); +} + +/* Declaration of the device attributes for the TPCI200 */ +static DEVICE_ATTR(description, S_IRUGO, + tpci200_show_description, NULL); +static DEVICE_ATTR(board_slot0, S_IRUGO | S_IWUSR, + tpci200_show_board_slot0, tpci200_store_board_slot0); +static DEVICE_ATTR(board_slot1, S_IRUGO | S_IWUSR, + tpci200_show_board_slot1, tpci200_store_board_slot1); +static DEVICE_ATTR(board_slot2, S_IRUGO | S_IWUSR, + tpci200_show_board_slot2, tpci200_store_board_slot2); +static DEVICE_ATTR(board_slot3, S_IRUGO | S_IWUSR, + tpci200_show_board_slot3, tpci200_store_board_slot3); + +static struct attribute *tpci200_attrs[] = { + &dev_attr_description.attr, + &dev_attr_board_slot0.attr, + &dev_attr_board_slot1.attr, + &dev_attr_board_slot2.attr, + &dev_attr_board_slot3.attr, + NULL, +}; + +static struct attribute_group tpci200_attr_group = { + .attrs = tpci200_attrs, +}; + +static int tpci200_create_sysfs_files(struct tpci200_board *card) +{ + return sysfs_create_group(&card->info->pdev->dev.kobj, + &tpci200_attr_group); +} + +static void tpci200_remove_sysfs_files(struct tpci200_board *card) +{ + sysfs_remove_group(&card->info->pdev->dev.kobj, &tpci200_attr_group); +} + +#else + +static int tpci200_create_sysfs_files(struct tpci200_board *card) +{ + return 0; +} + +static void tpci200_remove_sysfs_files(struct tpci200_board *card) +{ +} + +#endif /* CONFIG_SYSFS */ + +static int tpci200_register(struct tpci200_board *tpci200) +{ + int i; + int res; + unsigned long ioidint_base; + unsigned long mem_base; + unsigned short slot_ctrl; + + if (pci_enable_device(tpci200->info->pdev) < 0) + return -ENODEV; + + if (tpci200_create_sysfs_files(tpci200) < 0) { + pr_err("failed creating sysfs files\n"); + res = -EFAULT; + goto out_disable_pci; + } + + /* Request IP interface register (Bar 2) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, + "Carrier IP interface registers"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_remove_sysfs; + } + + /* Request IO ID INT space (Bar 3) */ + res = pci_request_region(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR, + "Carrier IO ID INT space"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ip_space; + } + + /* Request MEM space (Bar 4) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, + "Carrier MEM space"); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + /* Map internal tpci200 driver user space */ + tpci200->info->interface_regs = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_IP_INTERFACE_BAR), + TPCI200_IFACE_SIZE); + tpci200->info->ioidint_space = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR), + TPCI200_IOIDINT_SIZE); + tpci200->info->mem8_space = + ioremap(pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR), + TPCI200_MEM8_SIZE); + + spin_lock_init(&tpci200->info->access_lock); + ioidint_base = pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR); + mem_base = pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR); + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + + /* Set all slot physical address space */ + for (i = 0; i < TPCI200_NB_SLOT; i++) { + tpci200->slots[i].io_phys.address = + (void __iomem *)ioidint_base + + TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i; + tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; + + tpci200->slots[i].id_phys.address = + (void __iomem *)ioidint_base + + TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i; + tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; + + tpci200->slots[i].mem_phys.address = + (void __iomem *)mem_base + TPCI200_MEM8_GAP*i; + tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; + + writew(slot_ctrl, (tpci200->info->interface_regs + + control_reg[i])); + } + + res = request_irq(tpci200->info->pdev->irq, + tpci200_interrupt, IRQF_SHARED, + KBUILD_MODNAME, (void *) tpci200); + if (res) { + pr_err("(bn 0x%X, sn 0x%X) unable to register IRQ !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + tpci200_unregister(tpci200); + goto out_err; + } + + return 0; + +out_release_ioid_int_space: + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); +out_release_ip_space: + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); +out_remove_sysfs: + tpci200_remove_sysfs_files(tpci200); +out_disable_pci: + pci_disable_device(tpci200->info->pdev); +out_err: + return res; +} + +static int __tpci200_request_irq(struct tpci200_board *tpci200, + struct ipack_device *dev) +{ + unsigned short slot_ctrl; + + /* Set the default parameters of the slot + * INT0 enabled, level sensitive + * INT1 enabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = TPCI200_INT0_EN | TPCI200_INT1_EN; + writew(slot_ctrl, (tpci200->info->interface_regs + + control_reg[dev->slot])); + + return 0; +} + +static void __tpci200_free_irq(struct tpci200_board *tpci200, + struct ipack_device *dev) +{ + unsigned short slot_ctrl; + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + writew(slot_ctrl, (tpci200->info->interface_regs + + control_reg[dev->slot])); +} + +static int tpci200_free_irq(struct ipack_device *dev) +{ + int res; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + if (tpci200->slots[dev->slot].irq == NULL) { + res = -EINVAL; + goto out_unlock; + } + + __tpci200_free_irq(tpci200, dev); + slot_irq = tpci200->slots[dev->slot].irq; + tpci200->slots[dev->slot].irq = NULL; + kfree(slot_irq); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) +{ + int res; + struct ipack_addr_space *virt_addr_space; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + switch (space) { + case IPACK_IO_SPACE: + if (dev->io_space.address == NULL) { + pr_info("Slot [%d:%d] IO space not mapped !\n", + dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->io_space; + break; + case IPACK_ID_SPACE: + if (dev->id_space.address == NULL) { + pr_info("Slot [%d:%d] ID space not mapped !\n", + dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->id_space; + break; + case IPACK_MEM_SPACE: + if (dev->mem_space.address == NULL) { + pr_info("Slot [%d:%d] MEM space not mapped !\n", + dev->bus_nr, dev->slot); + goto out_unlock; + } + virt_addr_space = &dev->mem_space; + break; + default: + pr_err("Slot [%d:%d] space number %d doesn't exist !\n", + dev->bus_nr, dev->slot, space); + res = -EINVAL; + goto out_unlock; + break; + } + + iounmap(virt_addr_space->address); + + virt_addr_space->address = NULL; + virt_addr_space->size = 0; +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_slot_unregister(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + + if (dev == NULL) + return -ENODEV; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + tpci200_free_irq(dev); + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + ipack_device_unregister(dev); + tpci200->slots[dev->slot].dev = NULL; + mutex_unlock(&tpci200->mutex); + + return 0; +} + +static int tpci200_slot_map_space(struct ipack_device *dev, + unsigned int memory_size, int space) +{ + int res; + unsigned int size_to_map; + void __iomem *phys_address; + struct ipack_addr_space *virt_addr_space; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + switch (space) { + case IPACK_IO_SPACE: + if (dev->io_space.address != NULL) { + pr_err("Slot [%d:%d] IO space already mapped !\n", + tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->io_space; + + phys_address = tpci200->slots[dev->slot].io_phys.address; + size_to_map = tpci200->slots[dev->slot].io_phys.size; + break; + case IPACK_ID_SPACE: + if (dev->id_space.address != NULL) { + pr_err("Slot [%d:%d] ID space already mapped !\n", + tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->id_space; + + phys_address = tpci200->slots[dev->slot].id_phys.address; + size_to_map = tpci200->slots[dev->slot].id_phys.size; + break; + case IPACK_MEM_SPACE: + if (dev->mem_space.address != NULL) { + pr_err("Slot [%d:%d] MEM space already mapped !\n", + tpci200->number, dev->slot); + res = -EINVAL; + goto out_unlock; + } + virt_addr_space = &dev->mem_space; + + if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { + pr_err("Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n", + dev->bus_nr, dev->slot, memory_size, + tpci200->slots[dev->slot].mem_phys.size); + res = -EINVAL; + goto out_unlock; + } + + phys_address = tpci200->slots[dev->slot].mem_phys.address; + size_to_map = memory_size; + break; + default: + pr_err("Slot [%d:%d] space %d doesn't exist !\n", + tpci200->number, dev->slot, space); + res = -EINVAL; + goto out_unlock; + break; + } + + virt_addr_space->size = size_to_map; + virt_addr_space->address = + ioremap((unsigned long)phys_address, size_to_map); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static int tpci200_request_irq(struct ipack_device *dev, int vector, + int (*handler)(void *), void *arg) +{ + int res; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) { + res = -EINVAL; + goto out; + } + + if (mutex_lock_interruptible(&tpci200->mutex)) { + res = -ERESTARTSYS; + goto out; + } + + if (tpci200->slots[dev->slot].irq != NULL) { + pr_err("Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, + dev->slot); + res = -EINVAL; + goto out_unlock; + } + + slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + if (slot_irq == NULL) { + pr_err("Slot [%d:%d] unable to allocate memory for IRQ !\n", + dev->bus_nr, dev->slot); + res = -ENOMEM; + goto out_unlock; + } + + /* + * WARNING: Setup Interrupt Vector in the IndustryPack device + * before an IRQ request. + * Read the User Manual of your IndustryPack device to know + * where to write the vector in memory. + */ + slot_irq->vector = vector; + slot_irq->handler = handler; + slot_irq->arg = arg; + slot_irq->name = dev_name(&dev->dev); + + tpci200->slots[dev->slot].irq = slot_irq; + res = __tpci200_request_irq(tpci200, dev); + +out_unlock: + mutex_unlock(&tpci200->mutex); +out: + return res; +} + +static void tpci200_slot_remove(struct tpci200_slot *slot) +{ + if ((slot->dev == NULL) || + (slot->dev->driver->ops->remove == NULL)) + return; + + slot->dev->driver->ops->remove(slot->dev); +} + +static void tpci200_uninstall(struct tpci200_board *tpci200) +{ + int i; + + for (i = 0; i < TPCI200_NB_SLOT; i++) + tpci200_slot_remove(&tpci200->slots[i]); + + tpci200_unregister(tpci200); + kfree(tpci200->slots); +} + +static struct ipack_bus_ops tpci200_bus_ops = { + .map_space = tpci200_slot_map_space, + .unmap_space = tpci200_slot_unmap_space, + .request_irq = tpci200_request_irq, + .free_irq = tpci200_free_irq, + .read8 = tpci200_read8, + .read16 = tpci200_read16, + .read32 = tpci200_read32, + .write8 = tpci200_write8, + .write16 = tpci200_write16, + .write32 = tpci200_write32, + .remove_device = tpci200_slot_unregister, +}; + +static int tpci200_install(struct tpci200_board *tpci200) +{ + int res; + + tpci200->slots = kzalloc( + TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); + if (tpci200->slots == NULL) { + res = -ENOMEM; + goto out_err; + } + + res = tpci200_register(tpci200); + if (res) + goto out_free; + + mutex_init(&tpci200->mutex); + return 0; + +out_free: + kfree(tpci200->slots); + tpci200->slots = NULL; +out_err: + return res; +} + +static int tpci200_pciprobe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret; + struct tpci200_board *tpci200; + + tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); + if (!tpci200) + return -ENOMEM; + + tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); + if (!tpci200->info) { + kfree(tpci200); + return -ENOMEM; + } + + /* Save struct pci_dev pointer */ + tpci200->info->pdev = pdev; + tpci200->info->id_table = (struct pci_device_id *)id; + + /* register the device and initialize it */ + ret = tpci200_install(tpci200); + if (ret) { + pr_err("Error during tpci200 install !\n"); + kfree(tpci200->info); + kfree(tpci200); + return -ENODEV; + } + + /* Register the carrier in the industry pack bus driver */ + tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, + TPCI200_NB_SLOT, + &tpci200_bus_ops); + if (!tpci200->info->ipack_bus) { + pr_err("error registering the carrier on ipack driver\n"); + tpci200_uninstall(tpci200); + kfree(tpci200->info); + kfree(tpci200); + return -EFAULT; + } + + /* save the bus number given by ipack to logging purpose */ + tpci200->number = tpci200->info->ipack_bus->bus_nr; + dev_set_drvdata(&pdev->dev, tpci200); + /* add the registered device in an internal linked list */ + list_add_tail(&tpci200->list, &tpci200_list); + return ret; +} + +static void __tpci200_pci_remove(struct tpci200_board *tpci200) +{ + tpci200_uninstall(tpci200); + tpci200_remove_sysfs_files(tpci200); + list_del(&tpci200->list); + ipack_bus_unregister(tpci200->info->ipack_bus); + kfree(tpci200->info); + kfree(tpci200); +} + +static void __devexit tpci200_pci_remove(struct pci_dev *dev) +{ + struct tpci200_board *tpci200, *next; + + /* Search the registered device to uninstall it */ + list_for_each_entry_safe(tpci200, next, &tpci200_list, list) { + if (tpci200->info->pdev == dev) { + __tpci200_pci_remove(tpci200); + break; + } + } +} + +static struct pci_device_id tpci200_idtable[2] = { + { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, + TPCI200_SUBDEVICE_ID }, + { 0, }, +}; + +static struct pci_driver tpci200_pci_drv = { + .name = "tpci200", + .id_table = tpci200_idtable, + .probe = tpci200_pciprobe, + .remove = __devexit_p(tpci200_pci_remove), +}; + +static int __init tpci200_drvr_init_module(void) +{ + return pci_register_driver(&tpci200_pci_drv); +} + +static void __exit tpci200_drvr_exit_module(void) +{ + struct tpci200_board *tpci200, *next; + + list_for_each_entry_safe(tpci200, next, &tpci200_list, list) + __tpci200_pci_remove(tpci200); + + pci_unregister_driver(&tpci200_pci_drv); +} + +MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); +MODULE_LICENSE("GPL"); +module_init(tpci200_drvr_init_module); +module_exit(tpci200_drvr_exit_module); diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h new file mode 100644 index 0000000..0b547ee --- /dev/null +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -0,0 +1,162 @@ +/** + * tpci200.h + * + * driver for the carrier TEWS TPCI-200 + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#ifndef _TPCI200_H_ +#define _TPCI200_H_ + +#include <linux/version.h> +#include <linux/limits.h> +#include <linux/pci.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/swab.h> +#include <linux/io.h> + +#include "../ipack.h" + +#define TPCI200_NB_SLOT 0x4 +#define TPCI200_NB_BAR 0x6 + +#define TPCI200_VENDOR_ID 0x1498 +#define TPCI200_DEVICE_ID 0x30C8 +#define TPCI200_SUBVENDOR_ID 0x1498 +#define TPCI200_SUBDEVICE_ID 0x300A + +#define TPCI200_IP_INTERFACE_BAR 2 +#define TPCI200_IO_ID_INT_SPACES_BAR 3 +#define TPCI200_MEM16_SPACE_BAR 4 +#define TPCI200_MEM8_SPACE_BAR 5 + +#define TPCI200_REVISION_REG 0x00 +#define TPCI200_CONTROL_A_REG 0x02 +#define TPCI200_CONTROL_B_REG 0x04 +#define TPCI200_CONTROL_C_REG 0x06 +#define TPCI200_CONTROL_D_REG 0x08 +#define TPCI200_RESET_REG 0x0A +#define TPCI200_STATUS_REG 0x0C + +#define TPCI200_IFACE_SIZE 0x100 + +#define TPCI200_IO_SPACE_OFF 0x0000 +#define TPCI200_IO_SPACE_GAP 0x0100 +#define TPCI200_IO_SPACE_SIZE 0x0080 +#define TPCI200_ID_SPACE_OFF 0x0080 +#define TPCI200_ID_SPACE_GAP 0x0100 +#define TPCI200_ID_SPACE_SIZE 0x0040 +#define TPCI200_INT_SPACE_OFF 0x00C0 +#define TPCI200_INT_SPACE_GAP 0x0100 +#define TPCI200_INT_SPACE_SIZE 0x0040 +#define TPCI200_IOIDINT_SIZE 0x0400 + +#define TPCI200_MEM8_GAP 0x00400000 +#define TPCI200_MEM8_SIZE 0x00400000 +#define TPCI200_MEM16_GAP 0x00800000 +#define TPCI200_MEM16_SIZE 0x00800000 + +#define TPCI200_INT0_EN 0x0040 +#define TPCI200_INT1_EN 0x0080 +#define TPCI200_INT0_EDGE 0x0010 +#define TPCI200_INT1_EDGE 0x0020 +#define TPCI200_ERR_INT_EN 0x0008 +#define TPCI200_TIME_INT_EN 0x0004 +#define TPCI200_RECOVER_EN 0x0002 +#define TPCI200_CLK32 0x0001 + +#define TPCI200_A_RESET 0x0001 +#define TPCI200_B_RESET 0x0002 +#define TPCI200_C_RESET 0x0004 +#define TPCI200_D_RESET 0x0008 + +#define TPCI200_A_TIMEOUT 0x1000 +#define TPCI200_B_TIMEOUT 0x2000 +#define TPCI200_C_TIMEOUT 0x4000 +#define TPCI200_D_TIMEOUT 0x8000 + +#define TPCI200_A_ERROR 0x0100 +#define TPCI200_B_ERROR 0x0200 +#define TPCI200_C_ERROR 0x0400 +#define TPCI200_D_ERROR 0x0800 + +#define TPCI200_A_INT0 0x0001 +#define TPCI200_A_INT1 0x0002 +#define TPCI200_B_INT0 0x0004 +#define TPCI200_B_INT1 0x0008 +#define TPCI200_C_INT0 0x0010 +#define TPCI200_C_INT1 0x0020 +#define TPCI200_D_INT0 0x0040 +#define TPCI200_D_INT1 0x0080 + +#define TPCI200_SLOT_INT_MASK 0x00FF + +#define VME_IOID_SPACE "IOID" +#define VME_MEM_SPACE "MEM" + +/** + * struct slot_irq - slot IRQ definition. + * @vector Vector number + * @handler Handler called when IRQ arrives + * @arg Handler argument + * @name IRQ name + * + */ +struct slot_irq { + int vector; + int (*handler)(void *); + void *arg; + const char *name; +}; + +/** + * struct tpci200_slot - data specific to the tpci200 slot. + * @slot_id Slot identification gived to external interface + * @irq Slot IRQ infos + * @io_phys IO physical base address register of the slot + * @id_phys ID physical base address register of the slot + * @mem_phys MEM physical base address register of the slot + * + */ +struct tpci200_slot { + struct ipack_device *dev; + struct slot_irq *irq; + struct ipack_addr_space io_phys; + struct ipack_addr_space id_phys; + struct ipack_addr_space mem_phys; +}; + +/** + * struct tpci200_infos - informations specific of the TPCI200 tpci200. + * @pci_dev PCI device + * @interface_regs Pointer to IP interface space (Bar 2) + * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) + * @mem8_space Pointer to MEM space (Bar 4) + * @access_lock Mutex lock for simultaneous access + * + */ +struct tpci200_infos { + struct pci_dev *pdev; + struct pci_device_id *id_table; + void __iomem *interface_regs; + void __iomem *ioidint_space; + void __iomem *mem8_space; + spinlock_t access_lock; + struct ipack_bus_device *ipack_bus; +}; +struct tpci200_board { + struct list_head list; + unsigned int number; + struct mutex mutex; + struct tpci200_slot *slots; + struct tpci200_infos *info; +}; + +#endif /* _TPCI200_H_ */ diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig new file mode 100644 index 0000000..39f7188 --- /dev/null +++ b/drivers/staging/ipack/devices/Kconfig @@ -0,0 +1,7 @@ +config SERIAL_IPOCTAL + tristate "IndustryPack IP-OCTAL uart support" + depends on IPACK_BUS + help + This driver supports the IPOCTAL serial port device for the IndustryPack bus. + default n + diff --git a/drivers/staging/ipack/devices/Makefile b/drivers/staging/ipack/devices/Makefile new file mode 100644 index 0000000..6de18bd --- /dev/null +++ b/drivers/staging/ipack/devices/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SERIAL_IPOCTAL) += ipoctal.o diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c new file mode 100644 index 0000000..29f6fa8 --- /dev/null +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -0,0 +1,901 @@ +/** + * ipoctal.c + * + * driver for the GE IP-OCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/device.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/interrupt.h> +#include <linux/fs.h> +#include <linux/delay.h> +#include <linux/sched.h> +#include <linux/tty.h> +#include <linux/serial.h> +#include <linux/tty_flip.h> +#include <linux/slab.h> +#include <linux/uaccess.h> +#include <linux/atomic.h> +#include "../ipack.h" +#include "ipoctal.h" +#include "scc2698.h" + +#define IP_OCTAL_MANUFACTURER_ID 0xF0 +#define IP_OCTAL_232_ID 0x22 +#define IP_OCTAL_422_ID 0x2A +#define IP_OCTAL_485_ID 0x48 + +#define IP_OCTAL_ID_SPACE_VECTOR 0x41 +#define IP_OCTAL_NB_BLOCKS 4 + +static struct ipack_driver driver; +static const struct tty_operations ipoctal_fops; + +struct ipoctal { + struct list_head list; + struct ipack_device *dev; + unsigned int board_id; + struct scc2698_channel *chan_regs; + struct scc2698_block *block_regs; + struct ipoctal_stats chan_stats[NR_CHANNELS]; + char *buffer[NR_CHANNELS]; + unsigned int nb_bytes[NR_CHANNELS]; + unsigned int count_wr[NR_CHANNELS]; + struct ipoctal_config chan_config[NR_CHANNELS]; + wait_queue_head_t queue[NR_CHANNELS]; + unsigned short error_flag[NR_CHANNELS]; + spinlock_t lock[NR_CHANNELS]; + unsigned int pointer_read[NR_CHANNELS]; + unsigned int pointer_write[NR_CHANNELS]; + atomic_t open[NR_CHANNELS]; + unsigned char write; + struct tty_port tty_port[NR_CHANNELS]; + struct tty_driver *tty_drv; +}; + +/* Linked list to save the registered devices */ +static LIST_HEAD(ipoctal_list); + +static inline void ipoctal_write_io_reg(struct ipoctal *ipoctal, + unsigned char *dest, + unsigned char value) +{ + unsigned long offset; + + offset = ((void __iomem *) dest) - ipoctal->dev->io_space.address; + ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_IO_SPACE, offset, + value); +} + +static inline void ipoctal_write_cr_cmd(struct ipoctal *ipoctal, + unsigned char *dest, + unsigned char value) +{ + ipoctal_write_io_reg(ipoctal, dest, value); +} + +static inline unsigned char ipoctal_read_io_reg(struct ipoctal *ipoctal, + unsigned char *src) +{ + unsigned long offset; + unsigned char value; + + offset = ((void __iomem *) src) - ipoctal->dev->io_space.address; + ipoctal->dev->bus->ops->read8(ipoctal->dev, IPACK_IO_SPACE, offset, + &value); + return value; +} + +static struct ipoctal *ipoctal_find_board(struct tty_struct *tty) +{ + struct ipoctal *p; + + list_for_each_entry(p, &ipoctal_list, list) { + if (tty->driver->major == p->tty_drv->major) + return p; + } + + return NULL; +} + +static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ipoctal *ipoctal; + int channel = tty->index; + + ipoctal = ipoctal_find_board(tty); + + if (ipoctal == NULL) { + pr_err("Device not found. Major %d\n", tty->driver->major); + return -ENODEV; + } + + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); + tty->driver_data = ipoctal; + + return 0; +} + +static int ipoctal_open(struct tty_struct *tty, struct file *file) +{ + int channel = tty->index; + int res; + struct ipoctal *ipoctal; + + ipoctal = ipoctal_find_board(tty); + + if (ipoctal == NULL) { + pr_err("Device not found. Major %d\n", tty->driver->major); + return -ENODEV; + } + + if (atomic_read(&ipoctal->open[channel])) + return -EBUSY; + + res = tty_port_open(&ipoctal->tty_port[channel], tty, file); + if (res) + return res; + + atomic_inc(&ipoctal->open[channel]); + return 0; +} + +static void ipoctal_reset_stats(struct ipoctal_stats *stats) +{ + stats->tx = 0; + stats->rx = 0; + stats->rcv_break = 0; + stats->framing_err = 0; + stats->overrun_err = 0; + stats->parity_err = 0; +} + +static void ipoctal_free_channel(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + if (ipoctal == NULL) + return; + + ipoctal_reset_stats(&ipoctal->chan_stats[channel]); + ipoctal->pointer_read[channel] = 0; + ipoctal->pointer_write[channel] = 0; + ipoctal->nb_bytes[channel] = 0; +} + +static void ipoctal_close(struct tty_struct *tty, struct file *filp) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + tty_port_close(&ipoctal->tty_port[channel], tty, filp); + + if (atomic_dec_and_test(&ipoctal->open[channel])) + ipoctal_free_channel(tty); +} + +static int ipoctal_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct ipoctal *ipoctal = tty->driver_data; + int channel = tty->index; + + icount->cts = 0; + icount->dsr = 0; + icount->rng = 0; + icount->dcd = 0; + icount->rx = ipoctal->chan_stats[channel].rx; + icount->tx = ipoctal->chan_stats[channel].tx; + icount->frame = ipoctal->chan_stats[channel].framing_err; + icount->parity = ipoctal->chan_stats[channel].parity_err; + icount->brk = ipoctal->chan_stats[channel].rcv_break; + return 0; +} + +static int ipoctal_irq_handler(void *arg) +{ + unsigned int channel; + unsigned int block; + unsigned char isr; + unsigned char sr; + unsigned char isr_tx_rdy, isr_rx_rdy; + unsigned char value; + unsigned char flag; + struct tty_struct *tty; + struct ipoctal *ipoctal = (struct ipoctal *) arg; + + /* Check all channels */ + for (channel = 0; channel < NR_CHANNELS; channel++) { + /* If there is no client, skip the check */ + if (!atomic_read(&ipoctal->open[channel])) + continue; + + tty = tty_port_tty_get(&ipoctal->tty_port[channel]); + if (!tty) + continue; + + /* + * The HW is organized in pair of channels. + * See which register we need to read from + */ + block = channel / 2; + isr = ipoctal_read_io_reg(ipoctal, + &ipoctal->block_regs[block].u.r.isr); + sr = ipoctal_read_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.r.sr); + + if ((channel % 2) == 1) { + isr_tx_rdy = isr & ISR_TxRDY_B; + isr_rx_rdy = isr & ISR_RxRDY_FFULL_B; + } else { + isr_tx_rdy = isr & ISR_TxRDY_A; + isr_rx_rdy = isr & ISR_RxRDY_FFULL_A; + } + + /* In case of RS-485, change from TX to RX when finishing TX. + * Half-duplex. + */ + if ((ipoctal->board_id == IP_OCTAL_485_ID) && + (sr & SR_TX_EMPTY) && + (ipoctal->nb_bytes[channel] == 0)) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_NEGATE_RTSN); + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); + ipoctal->write = 1; + wake_up_interruptible(&ipoctal->queue[channel]); + } + + /* RX data */ + if (isr_rx_rdy && (sr & SR_RX_READY)) { + value = ipoctal_read_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.r.rhr); + flag = TTY_NORMAL; + + /* Error: count statistics */ + if (sr & SR_ERROR) { + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + + if (sr & SR_OVERRUN_ERROR) { + ipoctal->error_flag[channel] |= UART_OVERRUN; + ipoctal->chan_stats[channel].overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + ipoctal->error_flag[channel] |= UART_PARITY; + ipoctal->chan_stats[channel].parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + ipoctal->error_flag[channel] |= UART_FRAMING; + ipoctal->chan_stats[channel].framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + ipoctal->error_flag[channel] |= UART_BREAK; + ipoctal->chan_stats[channel].rcv_break++; + flag = TTY_BREAK; + } + } + + tty_insert_flip_char(tty, value, flag); + } + + /* TX of each character */ + if (isr_tx_rdy && (sr & SR_TX_READY)) { + unsigned int *pointer_write = + &ipoctal->pointer_write[channel]; + + if (ipoctal->nb_bytes[channel] <= 0) { + ipoctal->nb_bytes[channel] = 0; + continue; + } + spin_lock(&ipoctal->lock[channel]); + value = ipoctal->buffer[channel][*pointer_write]; + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.thr, + value); + ipoctal->chan_stats[channel].tx++; + ipoctal->count_wr[channel]++; + (*pointer_write)++; + *pointer_write = *pointer_write % PAGE_SIZE; + ipoctal->nb_bytes[channel]--; + spin_unlock(&ipoctal->lock[channel]); + + if ((ipoctal->nb_bytes[channel] == 0) && + (waitqueue_active(&ipoctal->queue[channel]))) { + + if (ipoctal->board_id != IP_OCTAL_485_ID) { + ipoctal->write = 1; + wake_up_interruptible(&ipoctal->queue[channel]); + } + } + } + + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } + return IRQ_HANDLED; +} + +static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) +{ + unsigned char manufacturerID; + unsigned char board_id; + + dev->bus->ops->read8(dev, IPACK_ID_SPACE, + IPACK_IDPROM_OFFSET_MANUFACTURER_ID, &manufacturerID); + if (manufacturerID != IP_OCTAL_MANUFACTURER_ID) + return -ENODEV; + + dev->bus->ops->read8(dev, IPACK_ID_SPACE, + IPACK_IDPROM_OFFSET_MODEL, (unsigned char *)&board_id); + + switch (board_id) { + case IP_OCTAL_232_ID: + case IP_OCTAL_422_ID: + case IP_OCTAL_485_ID: + *id = board_id; + break; + default: + return -ENODEV; + } + + return 0; +} + +static const struct tty_port_operations ipoctal_tty_port_ops = { + .dtr_rts = NULL, + .activate = ipoctal_port_activate, +}; + +static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, + unsigned int slot, unsigned int vector) +{ + int res = 0; + int i; + struct tty_driver *tty; + char name[20]; + unsigned char board_id; + + res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, + IPACK_ID_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] ID space!\n", bus_nr, slot); + return res; + } + + res = ipoctal_check_model(ipoctal->dev, &board_id); + if (res) { + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, + IPACK_ID_SPACE); + goto out_unregister_id_space; + } + ipoctal->board_id = board_id; + + res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, + IPACK_IO_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); + goto out_unregister_id_space; + } + + res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, + 0x8000, IPACK_MEM_SPACE); + if (res) { + pr_err("Unable to map slot [%d:%d] MEM space!\n", bus_nr, slot); + goto out_unregister_io_space; + } + + /* Save the virtual address to access the registers easily */ + ipoctal->chan_regs = + (struct scc2698_channel *) ipoctal->dev->io_space.address; + ipoctal->block_regs = + (struct scc2698_block *) ipoctal->dev->io_space.address; + + /* Disable RX and TX before touching anything */ + for (i = 0; i < NR_CHANNELS ; i++) { + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + } + + for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.acr, + ACR_BRG_SET2); + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.opcr, + OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | + OPCR_MPOb_RTSN); + ipoctal_write_io_reg(ipoctal, + &ipoctal->block_regs[i].u.w.imr, + IMR_TxRDY_A | IMR_RxRDY_FFULL_A | + IMR_DELTA_BREAK_A | IMR_TxRDY_B | + IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B); + } + + /* + * IP-OCTAL has different addresses to copy its IRQ vector. + * Depending of the carrier these addresses are accesible or not. + * More info in the datasheet. + */ + ipoctal->dev->bus->ops->request_irq(ipoctal->dev, vector, + ipoctal_irq_handler, ipoctal); + ipoctal->dev->bus->ops->write8(ipoctal->dev, IPACK_ID_SPACE, 0, vector); + + /* Register the TTY device */ + + /* Each IP-OCTAL channel is a TTY port */ + tty = alloc_tty_driver(NR_CHANNELS); + + if (!tty) { + res = -ENOMEM; + goto out_unregister_slot_unmap; + } + + /* Fill struct tty_driver with ipoctal data */ + tty->owner = THIS_MODULE; + tty->driver_name = "ipoctal"; + sprintf(name, "ipoctal.%d.%d.", bus_nr, slot); + tty->name = name; + tty->major = 0; + + tty->minor_start = 0; + tty->type = TTY_DRIVER_TYPE_SERIAL; + tty->subtype = SERIAL_TYPE_NORMAL; + tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty->init_termios = tty_std_termios; + tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->init_termios.c_ispeed = 9600; + tty->init_termios.c_ospeed = 9600; + + tty_set_operations(tty, &ipoctal_fops); + res = tty_register_driver(tty); + if (res) { + pr_err("Can't register tty driver.\n"); + put_tty_driver(tty); + goto out_unregister_slot_unmap; + } + + /* Save struct tty_driver for use it when uninstalling the device */ + ipoctal->tty_drv = tty; + + for (i = 0; i < NR_CHANNELS; i++) { + tty_port_init(&ipoctal->tty_port[i]); + tty_port_alloc_xmit_buf(&ipoctal->tty_port[i]); + ipoctal->tty_port[i].ops = &ipoctal_tty_port_ops; + + ipoctal_reset_stats(&ipoctal->chan_stats[i]); + ipoctal->nb_bytes[i] = 0; + init_waitqueue_head(&ipoctal->queue[i]); + ipoctal->error_flag[i] = UART_NOERROR; + + spin_lock_init(&ipoctal->lock[i]); + ipoctal->pointer_read[i] = 0; + ipoctal->pointer_write[i] = 0; + ipoctal->nb_bytes[i] = 0; + tty_register_device(tty, i, NULL); + + /* + * Enable again the RX. TX will be enabled when + * there is something to send + */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[i].u.w.cr, + CR_ENABLE_RX); + } + + return 0; + +out_unregister_slot_unmap: + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); +out_unregister_io_space: + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); +out_unregister_id_space: + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); + return res; +} + +static inline int ipoctal_copy_write_buffer(struct ipoctal *ipoctal, + unsigned int channel, + const unsigned char *buf, + int count) +{ + unsigned long flags; + int i; + unsigned int *pointer_read = &ipoctal->pointer_read[channel]; + + /* Copy the bytes from the user buffer to the internal one */ + for (i = 0; i < count; i++) { + if (i <= (PAGE_SIZE - ipoctal->nb_bytes[channel])) { + spin_lock_irqsave(&ipoctal->lock[channel], flags); + ipoctal->tty_port[channel].xmit_buf[*pointer_read] = buf[i]; + *pointer_read = (*pointer_read + 1) % PAGE_SIZE; + ipoctal->nb_bytes[channel]++; + spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + } else { + break; + } + } + return i; +} + +static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, + const unsigned char *buf, int count) +{ + ipoctal->nb_bytes[channel] = 0; + ipoctal->count_wr[channel] = 0; + + ipoctal_copy_write_buffer(ipoctal, channel, buf, count); + + ipoctal->error_flag[channel] = UART_NOERROR; + + /* As the IP-OCTAL 485 only supports half duplex, do it manually */ + if (ipoctal->board_id == IP_OCTAL_485_ID) { + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX); + ipoctal_write_cr_cmd(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_ASSERT_RTSN); + } + + /* + * Send a packet and then disable TX to avoid failure after several send + * operations + */ + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_TX); + wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); + ipoctal_write_io_reg(ipoctal, + &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_TX); + + ipoctal->write = 0; + return ipoctal->count_wr[channel]; +} + +static int ipoctal_write_tty(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + unsigned int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return ipoctal_write(ipoctal, channel, buf, count); +} + +static int ipoctal_write_room(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return PAGE_SIZE - ipoctal->nb_bytes[channel]; +} + +static int ipoctal_chars_in_buffer(struct tty_struct *tty) +{ + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + return ipoctal->nb_bytes[channel]; +} + +static void ipoctal_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + unsigned int cflag; + unsigned char mr1 = 0; + unsigned char mr2 = 0; + unsigned char csr = 0; + unsigned int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + speed_t baud; + + cflag = tty->termios->c_cflag; + + /* Disable and reset everything before change the setup */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_RX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_MR); + + /* Set Bits per chars */ + switch (cflag & CSIZE) { + case CS6: + mr1 |= MR1_CHRL_6_BITS; + break; + case CS7: + mr1 |= MR1_CHRL_7_BITS; + break; + case CS8: + default: + mr1 |= MR1_CHRL_8_BITS; + /* By default, select CS8 */ + tty->termios->c_cflag = (cflag & ~CSIZE) | CS8; + break; + } + + /* Set Parity */ + if (cflag & PARENB) + if (cflag & PARODD) + mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD; + else + mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN; + else + mr1 |= MR1_PARITY_OFF; + + /* Mark or space parity is not supported */ + tty->termios->c_cflag &= ~CMSPAR; + + /* Set stop bits */ + if (cflag & CSTOPB) + mr2 |= MR2_STOP_BITS_LENGTH_2; + else + mr2 |= MR2_STOP_BITS_LENGTH_1; + + /* Set the flow control */ + switch (ipoctal->board_id) { + case IP_OCTAL_232_ID: + if (cflag & CRTSCTS) { + mr1 |= MR1_RxRTS_CONTROL_ON; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; + ipoctal->chan_config[channel].flow_control = 1; + } else { + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + } + break; + case IP_OCTAL_422_ID: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + break; + case IP_OCTAL_485_ID: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; + ipoctal->chan_config[channel].flow_control = 0; + break; + default: + return; + break; + } + + baud = tty_get_baud_rate(tty); + tty_termios_encode_baud_rate(tty->termios, baud, baud); + + /* Set baud rate */ + switch (tty->termios->c_ospeed) { + case 75: + csr |= TX_CLK_75 | RX_CLK_75; + break; + case 110: + csr |= TX_CLK_110 | RX_CLK_110; + break; + case 150: + csr |= TX_CLK_150 | RX_CLK_150; + break; + case 300: + csr |= TX_CLK_300 | RX_CLK_300; + break; + case 600: + csr |= TX_CLK_600 | RX_CLK_600; + break; + case 1200: + csr |= TX_CLK_1200 | RX_CLK_1200; + break; + case 1800: + csr |= TX_CLK_1800 | RX_CLK_1800; + break; + case 2000: + csr |= TX_CLK_2000 | RX_CLK_2000; + break; + case 2400: + csr |= TX_CLK_2400 | RX_CLK_2400; + break; + case 4800: + csr |= TX_CLK_4800 | RX_CLK_4800; + break; + case 9600: + csr |= TX_CLK_9600 | RX_CLK_9600; + break; + case 19200: + csr |= TX_CLK_19200 | RX_CLK_19200; + break; + case 38400: + default: + csr |= TX_CLK_38400 | RX_CLK_38400; + /* In case of default, we establish 38400 bps */ + tty_termios_encode_baud_rate(tty->termios, 38400, 38400); + break; + } + + mr1 |= MR1_ERROR_CHAR; + mr1 |= MR1_RxINT_RxRDY; + + /* Write the control registers */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr1); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.mr, mr2); + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.csr, csr); + + /* save the setup in the structure */ + ipoctal->chan_config[channel].baud = tty_get_baud_rate(tty); + ipoctal->chan_config[channel].bits_per_char = cflag & CSIZE; + ipoctal->chan_config[channel].parity = cflag & PARENB; + ipoctal->chan_config[channel].stop_bits = cflag & CSTOPB; + + /* Enable again the RX */ + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_ENABLE_RX); +} + +static void ipoctal_hangup(struct tty_struct *tty) +{ + unsigned long flags; + int channel = tty->index; + struct ipoctal *ipoctal = tty->driver_data; + + if (ipoctal == NULL) + return; + + spin_lock_irqsave(&ipoctal->lock[channel], flags); + ipoctal->nb_bytes[channel] = 0; + ipoctal->pointer_read[channel] = 0; + ipoctal->pointer_write[channel] = 0; + spin_unlock_irqrestore(&ipoctal->lock[channel], flags); + + tty_port_hangup(&ipoctal->tty_port[channel]); + + ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_DISABLE_RX | CR_DISABLE_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_RX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_TX); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_ERR_STATUS); + ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, + CR_CMD_RESET_MR); + + clear_bit(ASYNCB_INITIALIZED, &ipoctal->tty_port[channel].flags); + wake_up_interruptible(&ipoctal->tty_port[channel].open_wait); +} + +static const struct tty_operations ipoctal_fops = { + .ioctl = NULL, + .open = ipoctal_open, + .close = ipoctal_close, + .write = ipoctal_write_tty, + .set_termios = ipoctal_set_termios, + .write_room = ipoctal_write_room, + .chars_in_buffer = ipoctal_chars_in_buffer, + .get_icount = ipoctal_get_icount, + .hangup = ipoctal_hangup, +}; + +static int ipoctal_match(struct ipack_device *dev) +{ + int res; + unsigned char board_id; + + if ((!dev->bus->ops) || (!dev->bus->ops->map_space) || + (!dev->bus->ops->unmap_space)) + return 0; + + res = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE); + if (res) + return 0; + + res = ipoctal_check_model(dev, &board_id); + dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE); + if (!res) + return 1; + + return 0; +} + +static int ipoctal_probe(struct ipack_device *dev) +{ + int res; + struct ipoctal *ipoctal; + + ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL); + if (ipoctal == NULL) + return -ENOMEM; + + ipoctal->dev = dev; + res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot, dev->irq); + if (res) + goto out_uninst; + + list_add_tail(&ipoctal->list, &ipoctal_list); + return 0; + +out_uninst: + kfree(ipoctal); + return res; +} + +static void __ipoctal_remove(struct ipoctal *ipoctal) +{ + int i; + + for (i = 0; i < NR_CHANNELS; i++) { + tty_unregister_device(ipoctal->tty_drv, i); + tty_port_free_xmit_buf(&ipoctal->tty_port[i]); + } + + tty_unregister_driver(ipoctal->tty_drv); + put_tty_driver(ipoctal->tty_drv); + + /* Tell the carrier board to free all the resources for this device */ + if (ipoctal->dev->bus->ops->remove_device != NULL) + ipoctal->dev->bus->ops->remove_device(ipoctal->dev); + + list_del(&ipoctal->list); + kfree(ipoctal); +} + +static void ipoctal_remove(struct ipack_device *device) +{ + struct ipoctal *ipoctal, *next; + + list_for_each_entry_safe(ipoctal, next, &ipoctal_list, list) { + if (ipoctal->dev == device) + __ipoctal_remove(ipoctal); + } +} + +static struct ipack_driver_ops ipoctal_drv_ops = { + .match = ipoctal_match, + .probe = ipoctal_probe, + .remove = ipoctal_remove, +}; + +static int __init ipoctal_init(void) +{ + driver.ops = &ipoctal_drv_ops; + return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME); +} + +static void __exit ipoctal_exit(void) +{ + struct ipoctal *p, *next; + + list_for_each_entry_safe(p, next, &ipoctal_list, list) + __ipoctal_remove(p); + + ipack_driver_unregister(&driver); +} + +MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver"); +MODULE_LICENSE("GPL"); + +module_init(ipoctal_init); +module_exit(ipoctal_exit); diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h new file mode 100644 index 0000000..266f361 --- /dev/null +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -0,0 +1,80 @@ +/** + * ipoctal.h + * + * driver for the IPOCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#ifndef _IPOCTAL_H +#define _IPOCTAL_H_ + +#define NR_CHANNELS 8 +#define IPOCTAL_MAX_BOARDS 16 +#define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS) +#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +/** + * enum uart_parity_e - UART supported parity. + */ +enum uart_parity_e { + UART_NONE = 0, + UART_ODD = 1, + UART_EVEN = 2, +}; + +/** + * enum uart_error - UART error type + * + */ +enum uart_error { + UART_NOERROR = 0, /* No error during transmission */ + UART_TIMEOUT = 1 << 0, /* Timeout error */ + UART_OVERRUN = 1 << 1, /* Overrun error */ + UART_PARITY = 1 << 2, /* Parity error */ + UART_FRAMING = 1 << 3, /* Framing error */ + UART_BREAK = 1 << 4, /* Received break */ +}; + +/** + * struct ipoctal_config - Serial configuration + * + * @baud: Baud rate + * @stop_bits: Stop bits (1 or 2) + * @bits_per_char: data size in bits + * @parity + * @flow_control: Flow control management (RTS/CTS) (0 disabled, 1 enabled) + */ +struct ipoctal_config { + unsigned int baud; + unsigned int stop_bits; + unsigned int bits_per_char; + unsigned short parity; + unsigned int flow_control; +}; + +/** + * struct ipoctal_stats -- Stats since last reset + * + * @tx: Number of transmitted bytes + * @rx: Number of received bytes + * @overrun: Number of overrun errors + * @parity_err: Number of parity errors + * @framing_err: Number of framing errors + * @rcv_break: Number of break received + */ +struct ipoctal_stats { + unsigned long tx; + unsigned long rx; + unsigned long overrun_err; + unsigned long parity_err; + unsigned long framing_err; + unsigned long rcv_break; +}; + +#endif /* _IPOCTAL_H_ */ diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h new file mode 100644 index 0000000..47f6269 --- /dev/null +++ b/drivers/staging/ipack/devices/scc2698.h @@ -0,0 +1,228 @@ +/* + * scc2698.h + * + * driver for the IPOCTAL boards + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#ifndef SCC2698_H_ +#define SCC2698_H_ + +/* + * struct scc2698_channel - Channel access to scc2698 IO + * + * dn value are only spacer. + * + */ +struct scc2698_channel { + union { + struct { + unsigned char d0, mr; /* Mode register 1/2*/ + unsigned char d1, sr; /* Status register */ + unsigned char d2, r1; /* reserved */ + unsigned char d3, rhr; /* Receive holding register (R) */ + unsigned char junk[8]; /* other crap for block control */ + } r; /* Read access */ + struct { + unsigned char d0, mr; /* Mode register 1/2 */ + unsigned char d1, csr; /* Clock select register */ + unsigned char d2, cr; /* Command register */ + unsigned char d3, thr; /* Transmit holding register */ + unsigned char junk[8]; /* other crap for block control */ + } w; /* Write access */ + } u; +}; + +/* + * struct scc2698_block - Block access to scc2698 IO + * + * The scc2698 contain 4 block. + * Each block containt two channel a and b. + * dn value are only spacer. + * + */ +struct scc2698_block { + union { + struct { + unsigned char d0, mra; /* Mode register 1/2 (a) */ + unsigned char d1, sra; /* Status register (a) */ + unsigned char d2, r1; /* reserved */ + unsigned char d3, rhra; /* Receive holding register (a) */ + unsigned char d4, ipcr; /* Input port change register of block */ + unsigned char d5, isr; /* Interrupt status register of block */ + unsigned char d6, ctur; /* Counter timer upper register of block */ + unsigned char d7, ctlr; /* Counter timer lower register of block */ + unsigned char d8, mrb; /* Mode register 1/2 (b) */ + unsigned char d9, srb; /* Status register (b) */ + unsigned char da, r2; /* reserved */ + unsigned char db, rhrb; /* Receive holding register (b) */ + unsigned char dc, r3; /* reserved */ + unsigned char dd, ip; /* Input port register of block */ + unsigned char de, ctg; /* Start counter timer of block */ + unsigned char df, cts; /* Stop counter timer of block */ + } r; /* Read access */ + struct { + unsigned char d0, mra; /* Mode register 1/2 (a) */ + unsigned char d1, csra; /* Clock select register (a) */ + unsigned char d2, cra; /* Command register (a) */ + unsigned char d3, thra; /* Transmit holding register (a) */ + unsigned char d4, acr; /* Auxiliary control register of block */ + unsigned char d5, imr; /* Interrupt mask register of block */ + unsigned char d6, ctu; /* Counter timer upper register of block */ + unsigned char d7, ctl; /* Counter timer lower register of block */ + unsigned char d8, mrb; /* Mode register 1/2 (b) */ + unsigned char d9, csrb; /* Clock select register (a) */ + unsigned char da, crb; /* Command register (b) */ + unsigned char db, thrb; /* Transmit holding register (b) */ + unsigned char dc, r1; /* reserved */ + unsigned char dd, opcr; /* Output port configuration register of block */ + unsigned char de, r2; /* reserved */ + unsigned char df, r3; /* reserved */ + } w; /* Write access */ + } u; +} ; + +#define MR1_CHRL_5_BITS (0x0 << 0) +#define MR1_CHRL_6_BITS (0x1 << 0) +#define MR1_CHRL_7_BITS (0x2 << 0) +#define MR1_CHRL_8_BITS (0x3 << 0) +#define MR1_PARITY_EVEN (0x1 << 2) +#define MR1_PARITY_ODD (0x0 << 2) +#define MR1_PARITY_ON (0x0 << 3) +#define MR1_PARITY_FORCE (0x1 << 3) +#define MR1_PARITY_OFF (0x2 << 3) +#define MR1_PARITY_SPECIAL (0x3 << 3) +#define MR1_ERROR_CHAR (0x0 << 5) +#define MR1_ERROR_BLOCK (0x1 << 5) +#define MR1_RxINT_RxRDY (0x0 << 6) +#define MR1_RxINT_FFULL (0x1 << 6) +#define MR1_RxRTS_CONTROL_ON (0x1 << 7) +#define MR1_RxRTS_CONTROL_OFF (0x0 << 7) + +#define MR2_STOP_BITS_LENGTH_1 (0x7 << 0) +#define MR2_STOP_BITS_LENGTH_2 (0xF << 0) +#define MR2_CTS_ENABLE_TX_ON (0x1 << 4) +#define MR2_CTS_ENABLE_TX_OFF (0x0 << 4) +#define MR2_TxRTS_CONTROL_ON (0x1 << 5) +#define MR2_TxRTS_CONTROL_OFF (0x0 << 5) +#define MR2_CH_MODE_NORMAL (0x0 << 6) +#define MR2_CH_MODE_ECHO (0x1 << 6) +#define MR2_CH_MODE_LOCAL (0x2 << 6) +#define MR2_CH_MODE_REMOTE (0x3 << 6) + +#define CR_ENABLE_RX (0x1 << 0) +#define CR_DISABLE_RX (0x1 << 1) +#define CR_ENABLE_TX (0x1 << 2) +#define CR_DISABLE_TX (0x1 << 3) +#define CR_CMD_RESET_MR (0x1 << 4) +#define CR_CMD_RESET_RX (0x2 << 4) +#define CR_CMD_RESET_TX (0x3 << 4) +#define CR_CMD_RESET_ERR_STATUS (0x4 << 4) +#define CR_CMD_RESET_BREAK_CHANGE (0x5 << 4) +#define CR_CMD_START_BREAK (0x6 << 4) +#define CR_CMD_STOP_BREAK (0x7 << 4) +#define CR_CMD_ASSERT_RTSN (0x8 << 4) +#define CR_CMD_NEGATE_RTSN (0x9 << 4) +#define CR_CMD_SET_TIMEOUT_MODE (0xA << 4) +#define CR_CMD_DISABLE_TIMEOUT_MODE (0xC << 4) + +#define SR_RX_READY (0x1 << 0) +#define SR_FIFO_FULL (0x1 << 1) +#define SR_TX_READY (0x1 << 2) +#define SR_TX_EMPTY (0x1 << 3) +#define SR_OVERRUN_ERROR (0x1 << 4) +#define SR_PARITY_ERROR (0x1 << 5) +#define SR_FRAMING_ERROR (0x1 << 6) +#define SR_RECEIVED_BREAK (0x1 << 7) + +#define SR_ERROR (0xF0) + +#define ACR_DELTA_IP0_IRQ_EN (0x1 << 0) +#define ACR_DELTA_IP1_IRQ_EN (0x1 << 1) +#define ACR_DELTA_IP2_IRQ_EN (0x1 << 2) +#define ACR_DELTA_IP3_IRQ_EN (0x1 << 3) +#define ACR_CT_Mask (0x7 << 4) +#define ACR_CExt (0x0 << 4) +#define ACR_CTxCA (0x1 << 4) +#define ACR_CTxCB (0x2 << 4) +#define ACR_CClk16 (0x3 << 4) +#define ACR_TExt (0x4 << 4) +#define ACR_TExt16 (0x5 << 4) +#define ACR_TClk (0x6 << 4) +#define ACR_TClk16 (0x7 << 4) +#define ACR_BRG_SET1 (0x0 << 7) +#define ACR_BRG_SET2 (0x1 << 7) + +#define TX_CLK_75 (0x0 << 0) +#define TX_CLK_110 (0x1 << 0) +#define TX_CLK_38400 (0x2 << 0) +#define TX_CLK_150 (0x3 << 0) +#define TX_CLK_300 (0x4 << 0) +#define TX_CLK_600 (0x5 << 0) +#define TX_CLK_1200 (0x6 << 0) +#define TX_CLK_2000 (0x7 << 0) +#define TX_CLK_2400 (0x8 << 0) +#define TX_CLK_4800 (0x9 << 0) +#define TX_CLK_1800 (0xA << 0) +#define TX_CLK_9600 (0xB << 0) +#define TX_CLK_19200 (0xC << 0) +#define RX_CLK_75 (0x0 << 4) +#define RX_CLK_110 (0x1 << 4) +#define RX_CLK_38400 (0x2 << 4) +#define RX_CLK_150 (0x3 << 4) +#define RX_CLK_300 (0x4 << 4) +#define RX_CLK_600 (0x5 << 4) +#define RX_CLK_1200 (0x6 << 4) +#define RX_CLK_2000 (0x7 << 4) +#define RX_CLK_2400 (0x8 << 4) +#define RX_CLK_4800 (0x9 << 4) +#define RX_CLK_1800 (0xA << 4) +#define RX_CLK_9600 (0xB << 4) +#define RX_CLK_19200 (0xC << 4) + +#define OPCR_MPOa_RTSN (0x0 << 0) +#define OPCR_MPOa_C_TO (0x1 << 0) +#define OPCR_MPOa_TxC1X (0x2 << 0) +#define OPCR_MPOa_TxC16X (0x3 << 0) +#define OPCR_MPOa_RxC1X (0x4 << 0) +#define OPCR_MPOa_RxC16X (0x5 << 0) +#define OPCR_MPOa_TxRDY (0x6 << 0) +#define OPCR_MPOa_RxRDY_FF (0x7 << 0) + +#define OPCR_MPOb_RTSN (0x0 << 4) +#define OPCR_MPOb_C_TO (0x1 << 4) +#define OPCR_MPOb_TxC1X (0x2 << 4) +#define OPCR_MPOb_TxC16X (0x3 << 4) +#define OPCR_MPOb_RxC1X (0x4 << 4) +#define OPCR_MPOb_RxC16X (0x5 << 4) +#define OPCR_MPOb_TxRDY (0x6 << 4) +#define OPCR_MPOb_RxRDY_FF (0x7 << 4) + +#define OPCR_MPP_INPUT (0x0 << 7) +#define OPCR_MPP_OUTPUT (0x1 << 7) + +#define IMR_TxRDY_A (0x1 << 0) +#define IMR_RxRDY_FFULL_A (0x1 << 1) +#define IMR_DELTA_BREAK_A (0x1 << 2) +#define IMR_COUNTER_READY (0x1 << 3) +#define IMR_TxRDY_B (0x1 << 4) +#define IMR_RxRDY_FFULL_B (0x1 << 5) +#define IMR_DELTA_BREAK_B (0x1 << 6) +#define IMR_INPUT_PORT_CHANGE (0x1 << 7) + +#define ISR_TxRDY_A (0x1 << 0) +#define ISR_RxRDY_FFULL_A (0x1 << 1) +#define ISR_DELTA_BREAK_A (0x1 << 2) +#define ISR_COUNTER_READY (0x1 << 3) +#define ISR_TxRDY_B (0x1 << 4) +#define ISR_RxRDY_FFULL_B (0x1 << 5) +#define ISR_DELTA_BREAK_B (0x1 << 6) +#define ISR_INPUT_PORT_CHANGE (0x1 << 7) + +#endif /* SCC2698_H_ */ diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c new file mode 100644 index 0000000..2b4fa51 --- /dev/null +++ b/drivers/staging/ipack/ipack.c @@ -0,0 +1,205 @@ +/* + * Industry-pack bus support functions. + * + * (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include "ipack.h" + +#define to_ipack_dev(device) container_of(device, struct ipack_device, dev) +#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) + +/* used when allocating bus numbers */ +#define IPACK_MAXBUS 64 + +static DEFINE_MUTEX(ipack_mutex); + +struct ipack_busmap { + unsigned long busmap[IPACK_MAXBUS / (8*sizeof(unsigned long))]; +}; +static struct ipack_busmap busmap; + +static void ipack_device_release(struct device *dev) +{ + struct ipack_device *device = to_ipack_dev(dev); + kfree(device); +} + +static int ipack_bus_match(struct device *device, struct device_driver *driver) +{ + int ret; + struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(driver); + + if ((!drv->ops) || (!drv->ops->match)) + return -EINVAL; + + ret = drv->ops->match(dev); + if (ret) + dev->driver = drv; + + return 0; +} + +static int ipack_bus_probe(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + + if (!dev->driver->ops->probe) + return -EINVAL; + + return dev->driver->ops->probe(dev); +} + +static int ipack_bus_remove(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + + if (!dev->driver->ops->remove) + return -EINVAL; + + dev->driver->ops->remove(dev); + return 0; +} + +static struct bus_type ipack_bus_type = { + .name = "ipack", + .probe = ipack_bus_probe, + .match = ipack_bus_match, + .remove = ipack_bus_remove, +}; + +static int ipack_assign_bus_number(void) +{ + int busnum; + + mutex_lock(&ipack_mutex); + busnum = find_next_zero_bit(busmap.busmap, IPACK_MAXBUS, 1); + + if (busnum >= IPACK_MAXBUS) { + pr_err("too many buses\n"); + busnum = -1; + goto error_find_busnum; + } + + set_bit(busnum, busmap.busmap); + +error_find_busnum: + mutex_unlock(&ipack_mutex); + return busnum; +} + +struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, + struct ipack_bus_ops *ops) +{ + int bus_nr; + struct ipack_bus_device *bus; + + bus = kzalloc(sizeof(struct ipack_bus_device), GFP_KERNEL); + if (!bus) + return NULL; + + bus_nr = ipack_assign_bus_number(); + if (bus_nr < 0) { + kfree(bus); + return NULL; + } + + bus->bus_nr = bus_nr; + bus->parent = parent; + bus->slots = slots; + bus->ops = ops; + return bus; +} +EXPORT_SYMBOL_GPL(ipack_bus_register); + +int ipack_bus_unregister(struct ipack_bus_device *bus) +{ + mutex_lock(&ipack_mutex); + clear_bit(bus->bus_nr, busmap.busmap); + mutex_unlock(&ipack_mutex); + kfree(bus); + return 0; +} +EXPORT_SYMBOL_GPL(ipack_bus_unregister); + +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, + char *name) +{ + edrv->driver.owner = owner; + edrv->driver.name = name; + edrv->driver.bus = &ipack_bus_type; + return driver_register(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_register); + +void ipack_driver_unregister(struct ipack_driver *edrv) +{ + driver_unregister(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_unregister); + +struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, + int slot, int irqv) +{ + int ret; + struct ipack_device *dev; + + dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + if (!dev) + return NULL; + + dev->dev.bus = &ipack_bus_type; + dev->dev.release = ipack_device_release; + dev->dev.parent = bus->parent; + dev->slot = slot; + dev->bus_nr = bus->bus_nr; + dev->irq = irqv; + dev->bus = bus; + dev_set_name(&dev->dev, + "ipack-dev.%u.%u", dev->bus_nr, dev->slot); + + ret = device_register(&dev->dev); + if (ret < 0) { + pr_err("error registering the device.\n"); + dev->driver->ops->remove(dev); + kfree(dev); + return NULL; + } + + return dev; +} +EXPORT_SYMBOL_GPL(ipack_device_register); + +void ipack_device_unregister(struct ipack_device *dev) +{ + device_unregister(&dev->dev); +} +EXPORT_SYMBOL_GPL(ipack_device_unregister); + +static int __init ipack_init(void) +{ + return bus_register(&ipack_bus_type); +} + +static void __exit ipack_exit(void) +{ + bus_unregister(&ipack_bus_type); +} + +module_init(ipack_init); +module_exit(ipack_exit); + +MODULE_AUTHOR("Samuel Iglesias Gonsalvez <siglesias@igalia.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Industry-pack bus core"); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h new file mode 100644 index 0000000..8bc001e --- /dev/null +++ b/drivers/staging/ipack/ipack.h @@ -0,0 +1,183 @@ +/* + * Industry-pack bus. + * + * (C) 2011 Samuel Iglesias Gonsalvez <siglesia@cern.ch>, CERN + * (C) 2012 Samuel Iglesias Gonsalvez <siglesias@igalia.com>, Igalia + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + */ + +#include <linux/device.h> + +#define IPACK_IDPROM_OFFSET_I 0x01 +#define IPACK_IDPROM_OFFSET_P 0x03 +#define IPACK_IDPROM_OFFSET_A 0x05 +#define IPACK_IDPROM_OFFSET_C 0x07 +#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 +#define IPACK_IDPROM_OFFSET_MODEL 0x0B +#define IPACK_IDPROM_OFFSET_REVISION 0x0D +#define IPACK_IDPROM_OFFSET_RESERVED 0x0F +#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 +#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 +#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 +#define IPACK_IDPROM_OFFSET_CRC 0x17 + +struct ipack_bus_ops; +struct ipack_driver; + +enum ipack_space { + IPACK_IO_SPACE = 0, + IPACK_ID_SPACE = 1, + IPACK_MEM_SPACE = 2, +}; + +/** + * struct ipack_addr_space - Virtual address space mapped for a specified type. + * + * @address: virtual address + * @size: size of the mapped space + */ +struct ipack_addr_space { + void __iomem *address; + unsigned int size; +}; + +/** + * struct ipack_device + * + * @bus_nr: IP bus number where the device is plugged + * @slot: Slot where the device is plugged in the carrier board + * @irq: IRQ vector + * @driver: Pointer to the ipack_driver that manages the device + * @bus: ipack_bus_device where the device is plugged to. + * @id_space: Virtual address to ID space. + * @io_space: Virtual address to IO space. + * @mem_space: Virtual address to MEM space. + * @dev: device in kernel representation. + * + * Warning: Direct access to mapped memory is possible but the endianness + * is not the same with PCI carrier or VME carrier. The endianness is managed + * by the carrier board throught bus->ops. + */ +struct ipack_device { + unsigned int bus_nr; + unsigned int slot; + unsigned int irq; + struct ipack_driver *driver; + struct ipack_bus_device *bus; + struct ipack_addr_space id_space; + struct ipack_addr_space io_space; + struct ipack_addr_space mem_space; + struct device dev; +}; + +/** + * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device + * + * @match: Match function + * @probe: Probe function + * @remove: tell the driver that the carrier board wants to remove one device + */ + +struct ipack_driver_ops { + int (*match) (struct ipack_device *dev); + int (*probe) (struct ipack_device *dev); + void (*remove) (struct ipack_device *dev); +}; + +/** + * struct ipack_driver -- Specific data to each ipack board driver + * + * @driver: Device driver kernel representation + * @ops: Mezzanine driver operations specific for the ipack bus. + */ +struct ipack_driver { + struct device_driver driver; + struct ipack_driver_ops *ops; +}; + +/** + * struct ipack_bus_ops - available operations on a bridge module + * + * @map_space: map IP address space + * @unmap_space: unmap IP address space + * @request_irq: request IRQ + * @free_irq: free IRQ + * @read8: read unsigned char + * @read16: read unsigned short + * @read32: read unsigned int + * @write8: read unsigned char + * @write16: read unsigned short + * @write32: read unsigned int + * @remove_device: tell the bridge module that the device has been removed + */ +struct ipack_bus_ops { + int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); + int (*unmap_space) (struct ipack_device *dev, int space); + int (*request_irq) (struct ipack_device *dev, int vector, int (*handler)(void *), void *arg); + int (*free_irq) (struct ipack_device *dev); + int (*read8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char *value); + int (*read16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short *value); + int (*read32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int *value); + int (*write8) (struct ipack_device *dev, int space, unsigned long offset, unsigned char value); + int (*write16) (struct ipack_device *dev, int space, unsigned long offset, unsigned short value); + int (*write32) (struct ipack_device *dev, int space, unsigned long offset, unsigned int value); + int (*remove_device) (struct ipack_device *dev); +}; + +/** + * struct ipack_bus_device + * + * @dev: pointer to carrier device + * @slots: number of slots available + * @bus_nr: ipack bus number + * @ops: bus operations for the mezzanine drivers + */ +struct ipack_bus_device { + struct device *parent; + int slots; + int bus_nr; + struct ipack_bus_ops *ops; +}; + +/** + * ipack_bus_register -- register a new ipack bus + * + * @parent: pointer to the parent device, if any. + * @slots: number of slots available in the bus device. + * @ops: bus operations for the mezzanine drivers. + * + * The carrier board device should call this function to register itself as + * available bus device in ipack. + */ +struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, + struct ipack_bus_ops *ops); + +/** + * ipack_bus_unregister -- unregister an ipack bus + */ +int ipack_bus_unregister(struct ipack_bus_device *bus); + +/** + * ipack_driver_register -- Register a new driver + * + * Called by a ipack driver to register itself as a driver + * that can manage ipack devices. + */ +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, char *name); +void ipack_driver_unregister(struct ipack_driver *edrv); + +/** + * ipack_device_register -- register a new mezzanine device + * + * @bus: ipack bus device it is plugged to. + * @slot: slot position in the bus device. + * @irqv: IRQ vector for the mezzanine. + * + * Register a new ipack device (mezzanine device). The call is done by + * the carrier device driver. + */ +struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot, int irqv); +void ipack_device_unregister(struct ipack_device *dev); diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h deleted file mode 100644 index f8a5149..0000000 --- a/drivers/staging/line6/config.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Line6 Linux USB driver - 0.8.0 - * - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#ifndef CONFIG_H -#define CONFIG_H - - -#ifdef CONFIG_USB_DEBUG -#define DEBUG 1 -#endif - - -/* - * Development tools. - */ -#define DO_DEBUG_MESSAGES 0 -#define DO_DUMP_URB_SEND DO_DEBUG_MESSAGES -#define DO_DUMP_URB_RECEIVE DO_DEBUG_MESSAGES -#define DO_DUMP_PCM_SEND 0 -#define DO_DUMP_PCM_RECEIVE 0 -#define DO_DUMP_MIDI_SEND DO_DEBUG_MESSAGES -#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES -#define DO_DUMP_ANY (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \ - DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \ - DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE) -#define CREATE_RAW_FILE 0 - -#if DO_DEBUG_MESSAGES -#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \ - __func__, __FILE__, __LINE__) -#endif - -#if DO_DEBUG_MESSAGES -#define DEBUG_MESSAGES(x) (x) -#else -#define DEBUG_MESSAGES(x) -#endif - - -#endif diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 2e602e1..4513f78 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -92,15 +92,10 @@ const unsigned char line6_midi_id[] = { Code to request version of POD, Variax interface (and maybe other devices). */ -static const char line6_request_version0[] = { +static const char line6_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 }; -/* - Copy of version request code with GFP_KERNEL flag for use in URB. -*/ -static const char *line6_request_version; - struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; /** @@ -336,8 +331,21 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, */ int line6_version_request_async(struct usb_line6 *line6) { - return line6_send_raw_message_async(line6, line6_request_version, - sizeof(line6_request_version0)); + char *buffer; + int retval; + + buffer = kmalloc(sizeof(line6_request_version), GFP_ATOMIC); + if (buffer == NULL) { + dev_err(line6->ifcdev, "Out of memory"); + return -ENOMEM; + } + + memcpy(buffer, line6_request_version, sizeof(line6_request_version)); + + retval = line6_send_raw_message_async(line6, buffer, + sizeof(line6_request_version)); + kfree(buffer); + return retval; } /* @@ -1292,70 +1300,7 @@ static struct usb_driver line6_driver = { .id_table = line6_id_table, }; -/* - Module initialization. -*/ -static int __init line6_init(void) -{ - int i, retval; - - printk(KERN_INFO "%s driver version %s\n", DRIVER_NAME, DRIVER_VERSION); - - for (i = LINE6_MAX_DEVICES; i--;) - line6_devices[i] = NULL; - - retval = usb_register(&line6_driver); - - if (retval) { - printk(KERN_ERR KBUILD_MODNAME - ": usb_register failed. Error number %d\n", retval); - return retval; - } - - line6_request_version = kmalloc(sizeof(line6_request_version0), - GFP_KERNEL); - - if (line6_request_version == NULL) { - printk(KERN_ERR KBUILD_MODNAME ":Out of memory\n"); - return -ENOMEM; - } - - memcpy((char *)line6_request_version, line6_request_version0, - sizeof(line6_request_version0)); - - return retval; -} - -/* - Module cleanup. -*/ -static void __exit line6_exit(void) -{ - int i; - struct usb_line6 *line6; - struct snd_line6_pcm *line6pcm; - - /* stop all PCM channels */ - for (i = LINE6_MAX_DEVICES; i--;) { - line6 = line6_devices[i]; - - if (line6 == NULL) - continue; - - line6pcm = line6->line6pcm; - - if (line6pcm == NULL) - continue; - - line6_pcm_release(line6pcm, ~0); - } - - usb_deregister(&line6_driver); - kfree(line6_request_version); -} - -module_init(line6_init); -module_exit(line6_exit); +module_usb_driver(line6_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 13d0293..5040729 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -406,7 +406,7 @@ int line6_init_midi(struct usb_line6 *line6) line6midi->line6 = line6; - switch(line6->product) { + switch (line6->product) { case LINE6_DEVID_PODHD300: case LINE6_DEVID_PODHD500: line6midi->midi_mask_transmit = 1; diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c index 7b532e5..836e8c8 100644 --- a/drivers/staging/line6/midibuf.c +++ b/drivers/staging/line6/midibuf.c @@ -64,7 +64,7 @@ int line6_midibuf_init(struct MidiBuffer *this, int size, int split) void line6_midibuf_status(struct MidiBuffer *this) { - printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d " + pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d " "full=%d command_prev=%02x\n", this->size, this->split, this->pos_read, this->pos_write, this->full, this->command_prev); } diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 90d2d44..5e319e3 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -99,7 +99,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) unsigned long flags_new = flags_old | channels; unsigned long flags_final = flags_old; int err = 0; - + line6pcm->prev_fbuf = NULL; if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c index 5917657..9ce8c9d 100644 --- a/drivers/staging/media/as102/as102_fe.c +++ b/drivers/staging/media/as102/as102_fe.c @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/version.h> - #include "as102_drv.h" #include "as10x_types.h" #include "as10x_cmd.h" diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c index 1075fb1..b9670ee 100644 --- a/drivers/staging/media/as102/as102_fw.c +++ b/drivers/staging/media/as102/as102_fw.c @@ -230,11 +230,8 @@ int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) pr_info("%s: firmware: %s loaded with success\n", DRIVER_NAME, fw2); error: - /* free data buffer */ kfree(cmd_buf); - /* release firmware if needed */ - if (firmware != NULL) - release_firmware(firmware); + release_firmware(firmware); LEAVE(); return errno; diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c index 6875c88..aaf1bc2 100644 --- a/drivers/staging/media/as102/as102_usb_drv.c +++ b/drivers/staging/media/as102/as102_usb_drv.c @@ -367,7 +367,7 @@ static int as102_usb_probe(struct usb_interface *intf, ENTER(); /* This should never actually happen */ - if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) != + if (ARRAY_SIZE(as102_usb_id_table) != (sizeof(as102_device_names) / sizeof(const char *))) { pr_err("Device names table invalid size"); return -EINVAL; @@ -380,8 +380,7 @@ static int as102_usb_probe(struct usb_interface *intf, } /* Assign the user-friendly device name */ - for (i = 0; i < (sizeof(as102_usb_id_table) / - sizeof(struct usb_device_id)); i++) { + for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) { if (id == &as102_usb_id_table[i]) { as102_dev->name = as102_device_names[i]; as102_dev->elna_cfg = as102_elna_cfg[i]; diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h index fc2884a..1ad1ec5 100644 --- a/drivers/staging/media/as102/as102_usb_drv.h +++ b/drivers/staging/media/as102/as102_usb_drv.h @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/version.h> - #ifndef _AS102_USB_DRV_H_ #define _AS102_USB_DRV_H_ diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c index 9413b37..3cee3cd 100644 --- a/drivers/staging/media/easycap/easycap_ioctl.c +++ b/drivers/staging/media/easycap/easycap_ioctl.c @@ -26,6 +26,7 @@ /*****************************************************************************/ #include "easycap.h" +#include <linux/version.h> /*--------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README index 48f4476..aeba132 100644 --- a/drivers/staging/media/go7007/README +++ b/drivers/staging/media/go7007/README @@ -6,6 +6,6 @@ Todo: - testing? - handle churn in v4l layer. -Please send patchs to Greg Kroah-Hartman <greg@kroah.com> and Cc: Ross +Please send patches to Greg Kroah-Hartman <greg@linuxfoundation.org> and Cc: Ross Cohen <rcohen@snurgle.org> as well. diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c index 4e13251..7c5af4f 100644 --- a/drivers/staging/media/go7007/s2250-loader.c +++ b/drivers/staging/media/go7007/s2250-loader.c @@ -160,31 +160,7 @@ static struct usb_driver s2250loader_driver = { .id_table = s2250loader_ids, }; -static int __init s2250loader_init(void) -{ - int r; - unsigned i = 0; - - for (i = 0; i < MAX_DEVICES; i++) - s2250_dev_table[i] = NULL; - - r = usb_register(&s2250loader_driver); - if (r) { - printk(KERN_ERR "usb_register failed. Error number %d\n", r); - return -1; - } - - printk(KERN_INFO "s2250loader_init: driver registered\n"); - return 0; -} -module_init(s2250loader_init); - -static void __exit s2250loader_cleanup(void) -{ - printk(KERN_INFO "s2250loader_cleanup\n"); - usb_deregister(&s2250loader_driver); -} -module_exit(s2250loader_cleanup); +module_usb_driver(s2250loader_driver); MODULE_AUTHOR(""); MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251"); diff --git a/drivers/staging/mei/Kconfig b/drivers/staging/mei/Kconfig deleted file mode 100644 index 47d78a7..0000000 --- a/drivers/staging/mei/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -config INTEL_MEI - tristate "Intel Management Engine Interface (Intel MEI)" - depends on X86 && PCI && EXPERIMENTAL && WATCHDOG_CORE - help - The Intel Management Engine (Intel ME) provides Manageability, - Security and Media services for system containing Intel chipsets. - if selected /dev/mei misc device will be created. - - Supported Chipsets are: - 7 Series Chipset Family - 6 Series Chipset Family - 5 Series Chipset Family - 4 Series Chipset Family - Mobile 4 Series Chipset Family - ICH9 - 82946GZ/GL - 82G35 Express - 82Q963/Q965 - 82P965/G965 - Mobile PM965/GM965 - Mobile GME965/GLE960 - 82Q35 Express - 82G33/G31/P35/P31 Express - 82Q33 Express - 82X38/X48 Express - - For more information see - <http://software.intel.com/en-us/manageability/> diff --git a/drivers/staging/mei/Makefile b/drivers/staging/mei/Makefile deleted file mode 100644 index 57168db..0000000 --- a/drivers/staging/mei/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile - Intel Management Engine Interface (Intel MEI) Linux driver -# Copyright (c) 2010-2011, Intel Corporation. -# -obj-$(CONFIG_INTEL_MEI) += mei.o -mei-objs := init.o -mei-objs += interrupt.o -mei-objs += interface.o -mei-objs += iorw.o -mei-objs += main.o -mei-objs += wd.o diff --git a/drivers/staging/mei/TODO b/drivers/staging/mei/TODO deleted file mode 100644 index fc26601..0000000 --- a/drivers/staging/mei/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - Cleanup and split the timer function -Upon Unstaging: - - move mei.h to include/linux/mei.h - - Documentation/ioctl/ioctl-number.txt - - move mei.txt under Documentation/mei/ - - move mei-amt-version.c under Documentation/mei - - add hostprogs-y for mei-amt-version.c - - drop mei_version.h - - Updated MAINTAINERS diff --git a/drivers/staging/mei/hw.h b/drivers/staging/mei/hw.h deleted file mode 100644 index 24c4c96..0000000 --- a/drivers/staging/mei/hw.h +++ /dev/null @@ -1,332 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#ifndef _MEI_HW_TYPES_H_ -#define _MEI_HW_TYPES_H_ - -#include <linux/uuid.h> - -/* - * Timeouts - */ -#define MEI_INTEROP_TIMEOUT (HZ * 7) -#define MEI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ - -#define CONNECT_TIMEOUT 15 /* HPS definition */ -#define INIT_CLIENTS_TIMEOUT 15 /* HPS definition */ - -#define IAMTHIF_STALL_TIMER 12 /* seconds */ -#define IAMTHIF_READ_TIMER 10000 /* ms */ - -/* - * Internal Clients Number - */ -#define MEI_WD_HOST_CLIENT_ID 1 -#define MEI_IAMTHIF_HOST_CLIENT_ID 2 - -/* - * MEI device IDs - */ -#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */ -#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */ -#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */ -#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */ - -#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */ -#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */ - -#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */ -#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */ -#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */ -#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */ -#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */ - -#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */ -#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */ - -#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */ -#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */ - -#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */ -#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */ - -#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */ -#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */ - -#define MEI_DEV_ID_CPT_1 0x1C3A /* Cougerpoint */ -#define MEI_DEV_ID_PBG_1 0x1D3A /* PBG */ - -#define MEI_DEV_ID_PPT_1 0x1E3A /* Pantherpoint PPT */ -#define MEI_DEV_ID_PPT_2 0x1CBA /* Pantherpoint PPT */ -#define MEI_DEV_ID_PPT_3 0x1DBA /* Pantherpoint PPT */ - - -/* - * MEI HW Section - */ - -/* MEI registers */ -/* H_CB_WW - Host Circular Buffer (CB) Write Window register */ -#define H_CB_WW 0 -/* H_CSR - Host Control Status register */ -#define H_CSR 4 -/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */ -#define ME_CB_RW 8 -/* ME_CSR_HA - ME Control Status Host Access register (read only) */ -#define ME_CSR_HA 0xC - - -/* register bits of H_CSR (Host Control Status register) */ -/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */ -#define H_CBD 0xFF000000 -/* Host Circular Buffer Write Pointer */ -#define H_CBWP 0x00FF0000 -/* Host Circular Buffer Read Pointer */ -#define H_CBRP 0x0000FF00 -/* Host Reset */ -#define H_RST 0x00000010 -/* Host Ready */ -#define H_RDY 0x00000008 -/* Host Interrupt Generate */ -#define H_IG 0x00000004 -/* Host Interrupt Status */ -#define H_IS 0x00000002 -/* Host Interrupt Enable */ -#define H_IE 0x00000001 - - -/* register bits of ME_CSR_HA (ME Control Status Host Access register) */ -/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only -access to ME_CBD */ -#define ME_CBD_HRA 0xFF000000 -/* ME CB Write Pointer HRA - host read only access to ME_CBWP */ -#define ME_CBWP_HRA 0x00FF0000 -/* ME CB Read Pointer HRA - host read only access to ME_CBRP */ -#define ME_CBRP_HRA 0x0000FF00 -/* ME Reset HRA - host read only access to ME_RST */ -#define ME_RST_HRA 0x00000010 -/* ME Ready HRA - host read only access to ME_RDY */ -#define ME_RDY_HRA 0x00000008 -/* ME Interrupt Generate HRA - host read only access to ME_IG */ -#define ME_IG_HRA 0x00000004 -/* ME Interrupt Status HRA - host read only access to ME_IS */ -#define ME_IS_HRA 0x00000002 -/* ME Interrupt Enable HRA - host read only access to ME_IE */ -#define ME_IE_HRA 0x00000001 - -/* - * MEI Version - */ -#define HBM_MINOR_VERSION 0 -#define HBM_MAJOR_VERSION 1 -#define HBM_TIMEOUT 1 /* 1 second */ - -/* Host bus message command opcode */ -#define MEI_HBM_CMD_OP_MSK 0x7f -/* Host bus message command RESPONSE */ -#define MEI_HBM_CMD_RES_MSK 0x80 - -/* - * MEI Bus Message Command IDs - */ -#define HOST_START_REQ_CMD 0x01 -#define HOST_START_RES_CMD 0x81 - -#define HOST_STOP_REQ_CMD 0x02 -#define HOST_STOP_RES_CMD 0x82 - -#define ME_STOP_REQ_CMD 0x03 - -#define HOST_ENUM_REQ_CMD 0x04 -#define HOST_ENUM_RES_CMD 0x84 - -#define HOST_CLIENT_PROPERTIES_REQ_CMD 0x05 -#define HOST_CLIENT_PROPERTIES_RES_CMD 0x85 - -#define CLIENT_CONNECT_REQ_CMD 0x06 -#define CLIENT_CONNECT_RES_CMD 0x86 - -#define CLIENT_DISCONNECT_REQ_CMD 0x07 -#define CLIENT_DISCONNECT_RES_CMD 0x87 - -#define MEI_FLOW_CONTROL_CMD 0x08 - -/* - * MEI Stop Reason - * used by hbm_host_stop_request.reason - */ -enum mei_stop_reason_types { - DRIVER_STOP_REQUEST = 0x00, - DEVICE_D1_ENTRY = 0x01, - DEVICE_D2_ENTRY = 0x02, - DEVICE_D3_ENTRY = 0x03, - SYSTEM_S1_ENTRY = 0x04, - SYSTEM_S2_ENTRY = 0x05, - SYSTEM_S3_ENTRY = 0x06, - SYSTEM_S4_ENTRY = 0x07, - SYSTEM_S5_ENTRY = 0x08 -}; - -/* - * Client Connect Status - * used by hbm_client_connect_response.status - */ -enum client_connect_status_types { - CCS_SUCCESS = 0x00, - CCS_NOT_FOUND = 0x01, - CCS_ALREADY_STARTED = 0x02, - CCS_OUT_OF_RESOURCES = 0x03, - CCS_MESSAGE_SMALL = 0x04 -}; - -/* - * Client Disconnect Status - */ -enum client_disconnect_status_types { - CDS_SUCCESS = 0x00 -}; - -/* - * MEI BUS Interface Section - */ -struct mei_msg_hdr { - u32 me_addr:8; - u32 host_addr:8; - u32 length:9; - u32 reserved:6; - u32 msg_complete:1; -} __packed; - - -struct mei_bus_message { - u8 hbm_cmd; - u8 data[0]; -} __packed; - -struct hbm_version { - u8 minor_version; - u8 major_version; -} __packed; - -struct hbm_host_version_request { - u8 hbm_cmd; - u8 reserved; - struct hbm_version host_version; -} __packed; - -struct hbm_host_version_response { - u8 hbm_cmd; - u8 host_version_supported; - struct hbm_version me_max_version; -} __packed; - -struct hbm_host_stop_request { - u8 hbm_cmd; - u8 reason; - u8 reserved[2]; -} __packed; - -struct hbm_host_stop_response { - u8 hbm_cmd; - u8 reserved[3]; -} __packed; - -struct hbm_me_stop_request { - u8 hbm_cmd; - u8 reason; - u8 reserved[2]; -} __packed; - -struct hbm_host_enum_request { - u8 hbm_cmd; - u8 reserved[3]; -} __packed; - -struct hbm_host_enum_response { - u8 hbm_cmd; - u8 reserved[3]; - u8 valid_addresses[32]; -} __packed; - -struct mei_client_properties { - uuid_le protocol_name; - u8 protocol_version; - u8 max_number_of_connections; - u8 fixed_address; - u8 single_recv_buf; - u32 max_msg_length; -} __packed; - -struct hbm_props_request { - u8 hbm_cmd; - u8 address; - u8 reserved[2]; -} __packed; - - -struct hbm_props_response { - u8 hbm_cmd; - u8 address; - u8 status; - u8 reserved[1]; - struct mei_client_properties client_properties; -} __packed; - -struct hbm_client_connect_request { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved; -} __packed; - -struct hbm_client_connect_response { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 status; -} __packed; - -struct hbm_client_disconnect_request { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved[1]; -} __packed; - -#define MEI_FC_MESSAGE_RESERVED_LENGTH 5 - -struct hbm_flow_control { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH]; -} __packed; - -struct mei_me_client { - struct mei_client_properties props; - u8 client_id; - u8 mei_flow_ctrl_creds; -} __packed; - - -#endif diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c deleted file mode 100644 index eab711f..0000000 --- a/drivers/staging/mei/init.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include <linux/pci.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/delay.h> - -#include "mei_dev.h" -#include "hw.h" -#include "interface.h" -#include "mei.h" - -const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, - 0xa8, 0x46, 0xe0, 0xff, 0x65, - 0x81, 0x4c); - -/** - * mei_io_list_init - Sets up a queue list. - * - * @list: An instance io list structure - * @dev: the device structure - */ -void mei_io_list_init(struct mei_io_list *list) -{ - /* initialize our queue list */ - INIT_LIST_HEAD(&list->mei_cb.cb_list); -} - -/** - * mei_io_list_flush - removes list entry belonging to cl. - * - * @list: An instance of our list structure - * @cl: private data of the file object - */ -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) -{ - struct mei_cl_cb *pos; - struct mei_cl_cb *next; - - list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { - if (pos->file_private) { - struct mei_cl *cl_tmp; - cl_tmp = (struct mei_cl *)pos->file_private; - if (mei_cl_cmp_id(cl, cl_tmp)) - list_del(&pos->cb_list); - } - } -} -/** - * mei_cl_flush_queues - flushes queue lists belonging to cl. - * - * @dev: the device structure - * @cl: private data of the file object - */ -int mei_cl_flush_queues(struct mei_cl *cl) -{ - if (!cl || !cl->dev) - return -EINVAL; - - dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); - mei_io_list_flush(&cl->dev->read_list, cl); - mei_io_list_flush(&cl->dev->write_list, cl); - mei_io_list_flush(&cl->dev->write_waiting_list, cl); - mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); - mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); - mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); - mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); - return 0; -} - - - -/** - * mei_reset_iamthif_params - initializes mei device iamthif - * - * @dev: the device structure - */ -static void mei_reset_iamthif_params(struct mei_device *dev) -{ - /* reset iamthif parameters. */ - dev->iamthif_current_cb = NULL; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = false; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; -} - -/** - * init_mei_device - allocates and initializes the mei device structure - * - * @pdev: The pci device structure - * - * returns The mei_device_device pointer on success, NULL on failure. - */ -struct mei_device *mei_device_init(struct pci_dev *pdev) -{ - struct mei_device *dev; - - dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL); - if (!dev) - return NULL; - - /* setup our list array */ - INIT_LIST_HEAD(&dev->file_list); - INIT_LIST_HEAD(&dev->wd_cl.link); - INIT_LIST_HEAD(&dev->iamthif_cl.link); - mutex_init(&dev->device_lock); - init_waitqueue_head(&dev->wait_recvd_msg); - init_waitqueue_head(&dev->wait_stop_wd); - dev->mei_state = MEI_INITIALIZING; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->wd_interface_reg = false; - - - mei_io_list_init(&dev->read_list); - mei_io_list_init(&dev->write_list); - mei_io_list_init(&dev->write_waiting_list); - mei_io_list_init(&dev->ctrl_wr_list); - mei_io_list_init(&dev->ctrl_rd_list); - mei_io_list_init(&dev->amthi_cmd_list); - mei_io_list_init(&dev->amthi_read_complete_list); - dev->pdev = pdev; - return dev; -} - -/** - * mei_hw_init - initializes host and fw to start work. - * - * @dev: the device structure - * - * returns 0 on success, <0 on failure. - */ -int mei_hw_init(struct mei_device *dev) -{ - int err = 0; - int ret; - - mutex_lock(&dev->device_lock); - - dev->host_hw_state = mei_hcsr_read(dev); - dev->me_hw_state = mei_mecsr_read(dev); - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - /* acknowledge interrupt and stop interupts */ - if ((dev->host_hw_state & H_IS) == H_IS) - mei_reg_write(dev, H_CSR, dev->host_hw_state); - - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); - - mei_reset(dev, 1); - - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - /* wait for ME to turn on ME_RDY */ - if (!dev->recvd_msg) { - mutex_unlock(&dev->device_lock); - err = wait_event_interruptible_timeout(dev->wait_recvd_msg, - dev->recvd_msg, MEI_INTEROP_TIMEOUT); - mutex_lock(&dev->device_lock); - } - - if (err <= 0 && !dev->recvd_msg) { - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, - "wait_event_interruptible_timeout failed" - "on wait for ME to turn on ME_RDY.\n"); - ret = -ENODEV; - goto out; - } - - if (!(((dev->host_hw_state & H_RDY) == H_RDY) && - ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) { - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, - "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if (!(dev->host_hw_state & H_RDY)) - dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n"); - - if (!(dev->me_hw_state & ME_RDY_HRA)) - dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n"); - - printk(KERN_ERR "mei: link layer initialization failed.\n"); - ret = -ENODEV; - goto out; - } - - if (dev->version.major_version != HBM_MAJOR_VERSION || - dev->version.minor_version != HBM_MINOR_VERSION) { - dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); - ret = -ENODEV; - goto out; - } - - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n"); - dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); - dev_dbg(&dev->pdev->dev, "MEI start success.\n"); - ret = 0; - -out: - mutex_unlock(&dev->device_lock); - return ret; -} - -/** - * mei_hw_reset - resets fw via mei csr register. - * - * @dev: the device structure - * @interrupts_enabled: if interrupt should be enabled after reset. - */ -static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled) -{ - dev->host_hw_state |= (H_RST | H_IG); - - if (interrupts_enabled) - mei_enable_interrupts(dev); - else - mei_disable_interrupts(dev); -} - -/** - * mei_reset - resets host and fw. - * - * @dev: the device structure - * @interrupts_enabled: if interrupt should be enabled after reset. - */ -void mei_reset(struct mei_device *dev, int interrupts_enabled) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - bool unexpected; - - if (dev->mei_state == MEI_RECOVERING_FROM_RESET) { - dev->need_reset = true; - return; - } - - unexpected = (dev->mei_state != MEI_INITIALIZING && - dev->mei_state != MEI_DISABLED && - dev->mei_state != MEI_POWER_DOWN && - dev->mei_state != MEI_POWER_UP); - - dev->host_hw_state = mei_hcsr_read(dev); - - dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - mei_hw_reset(dev, interrupts_enabled); - - dev->host_hw_state &= ~H_RST; - dev->host_hw_state |= H_IG; - - mei_hcsr_set(dev); - - dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - dev->need_reset = false; - - if (dev->mei_state != MEI_INITIALIZING) { - if (dev->mei_state != MEI_DISABLED && - dev->mei_state != MEI_POWER_DOWN) - dev->mei_state = MEI_RESETING; - - list_for_each_entry_safe(cl_pos, - cl_next, &dev->file_list, link) { - cl_pos->state = MEI_FILE_DISCONNECTED; - cl_pos->mei_flow_ctrl_creds = 0; - cl_pos->read_cb = NULL; - cl_pos->timer_count = 0; - } - /* remove entry if already in list */ - dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, - dev->wd_cl.host_client_id); - - mei_remove_client_from_file_list(dev, - dev->iamthif_cl.host_client_id); - - mei_reset_iamthif_params(dev); - dev->wd_due_counter = 0; - dev->extra_write_index = 0; - } - - dev->me_clients_num = 0; - dev->rd_msg_hdr = 0; - dev->stop = false; - dev->wd_pending = false; - - /* update the state of the registers after reset */ - dev->host_hw_state = mei_hcsr_read(dev); - dev->me_hw_state = mei_mecsr_read(dev); - - dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", - dev->host_hw_state, dev->me_hw_state); - - if (unexpected) - dev_warn(&dev->pdev->dev, "unexpected reset.\n"); - - /* Wake up all readings so they can be interrupted */ - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (waitqueue_active(&cl_pos->rx_wait)) { - dev_dbg(&dev->pdev->dev, "Waking up client!\n"); - wake_up_interruptible(&cl_pos->rx_wait); - } - } - /* remove all waiting requests */ - list_for_each_entry_safe(cb_pos, cb_next, - &dev->write_list.mei_cb.cb_list, cb_list) { - list_del(&cb_pos->cb_list); - mei_free_cb_private(cb_pos); - } -} - - - -/** - * host_start_message - mei host sends start message. - * - * @dev: the device structure - * - * returns none. - */ -void mei_host_start_message(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_host_version_request *host_start_req; - - /* host start message */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_version_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_start_req = - (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; - memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); - host_start_req->hbm_cmd = HOST_START_REQ_CMD; - host_start_req->host_version.major_version = HBM_MAJOR_VERSION; - host_start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->recvd_msg = false; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, - mei_hdr->length)) { - dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); - dev->mei_state = MEI_RESETING; - mei_reset(dev, 1); - } - dev->init_clients_state = MEI_START_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - return ; -} - -/** - * host_enum_clients_message - host sends enumeration client request message. - * - * @dev: the device structure - * - * returns none. - */ -void mei_host_enum_clients_message(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_host_enum_request *host_enum_req; - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - /* enumerate clients */ - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_enum_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; - memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); - host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, - mei_hdr->length)) { - dev->mei_state = MEI_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); - mei_reset(dev, 1); - } - dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - return; -} - - -/** - * allocate_me_clients_storage - allocates storage for me clients - * - * @dev: the device structure - * - * returns none. - */ -void mei_allocate_me_clients_storage(struct mei_device *dev) -{ - struct mei_me_client *clients; - int b; - - /* count how many ME clients we have */ - for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) - dev->me_clients_num++; - - if (dev->me_clients_num <= 0) - return ; - - - if (dev->me_clients != NULL) { - kfree(dev->me_clients); - dev->me_clients = NULL; - } - dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", - dev->me_clients_num * sizeof(struct mei_me_client)); - /* allocate storage for ME clients representation */ - clients = kcalloc(dev->me_clients_num, - sizeof(struct mei_me_client), GFP_KERNEL); - if (!clients) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); - dev->mei_state = MEI_RESETING; - mei_reset(dev, 1); - return ; - } - dev->me_clients = clients; - return ; -} -/** - * host_client_properties - reads properties for client - * - * @dev: the device structure - * - * returns: - * < 0 - Error. - * = 0 - no more clients. - * = 1 - still have clients to send properties request. - */ -int mei_host_client_properties(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_header; - struct hbm_props_request *host_cli_req; - int b; - u8 client_num = dev->me_client_presentation_num; - - b = dev->me_client_index; - b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); - if (b < MEI_CLIENTS_MAX) { - dev->me_clients[client_num].client_id = b; - dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_header->host_addr = 0; - mei_header->me_addr = 0; - mei_header->length = sizeof(struct hbm_props_request); - mei_header->msg_complete = 1; - mei_header->reserved = 0; - - host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; - - memset(host_cli_req, 0, sizeof(struct hbm_props_request)); - - host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - host_cli_req->address = b; - - if (mei_write_message(dev, mei_header, - (unsigned char *)host_cli_req, - mei_header->length)) { - dev->mei_state = MEI_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); - mei_reset(dev, 1); - return -EIO; - } - - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; - dev->me_client_index = b; - return 1; - } - - return 0; -} - -/** - * mei_init_file_private - initializes private file structure. - * - * @priv: private file structure to be initialized - * @file: the file structure - */ -void mei_cl_init(struct mei_cl *priv, struct mei_device *dev) -{ - memset(priv, 0, sizeof(struct mei_cl)); - init_waitqueue_head(&priv->wait); - init_waitqueue_head(&priv->rx_wait); - init_waitqueue_head(&priv->tx_wait); - INIT_LIST_HEAD(&priv->link); - priv->reading_state = MEI_IDLE; - priv->writing_state = MEI_IDLE; - priv->dev = dev; -} - -int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid) -{ - int i, res = -1; - - for (i = 0; i < dev->me_clients_num; ++i) - if (uuid_le_cmp(cuuid, - dev->me_clients[i].props.protocol_name) == 0) { - res = i; - break; - } - - return res; -} - - -/** - * mei_find_me_client_update_filext - searches for ME client guid - * sets client_id in mei_file_private if found - * @dev: the device structure - * @priv: private file structure to set client_id in - * @cguid: searched guid of ME client - * @client_id: id of host client to be set in file private structure - * - * returns ME client index - */ -u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv, - const uuid_le *cguid, u8 client_id) -{ - int i; - - if (!dev || !priv || !cguid) - return 0; - - /* check for valid client id */ - i = mei_find_me_client_index(dev, *cguid); - if (i >= 0) { - priv->me_client_id = dev->me_clients[i].client_id; - priv->state = MEI_FILE_CONNECTING; - priv->host_client_id = client_id; - - list_add_tail(&priv->link, &dev->file_list); - return (u8)i; - } - - return 0; -} - -/** - * host_init_iamthif - mei initialization iamthif client. - * - * @dev: the device structure - * - */ -void mei_host_init_iamthif(struct mei_device *dev) -{ - u8 i; - unsigned char *msg_buf; - - mei_cl_init(&dev->iamthif_cl, dev); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - - /* find ME amthi client */ - i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl, - &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); - if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) { - dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); - return; - } - - /* Assign iamthif_mtu to the value received from ME */ - - dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; - dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", - dev->me_clients[i].props.max_msg_length); - - kfree(dev->iamthif_msg_buf); - dev->iamthif_msg_buf = NULL; - - /* allocate storage for ME message buffer */ - msg_buf = kcalloc(dev->iamthif_mtu, - sizeof(unsigned char), GFP_KERNEL); - if (!msg_buf) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); - return; - } - - dev->iamthif_msg_buf = msg_buf; - - if (mei_connect(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - dev->iamthif_cl.host_client_id = 0; - } else { - dev->iamthif_cl.timer_count = CONNECT_TIMEOUT; - } -} - -/** - * mei_alloc_file_private - allocates a private file structure and sets it up. - * @file: the file structure - * - * returns The allocated file or NULL on failure - */ -struct mei_cl *mei_cl_allocate(struct mei_device *dev) -{ - struct mei_cl *cl; - - cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); - if (!cl) - return NULL; - - mei_cl_init(cl, dev); - - return cl; -} - - - -/** - * mei_disconnect_host_client - sends disconnect message to fw from host client. - * - * @dev: the device structure - * @cl: private data of the file object - * - * Locking: called under "dev->device_lock" lock - * - * returns 0 on success, <0 on failure. - */ -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) -{ - int rets, err; - long timeout = 15; /* 15 seconds */ - struct mei_cl_cb *cb; - - if (!dev || !cl) - return -ENODEV; - - if (cl->state != MEI_FILE_DISCONNECTING) - return 0; - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return -ENOMEM; - - INIT_LIST_HEAD(&cb->cb_list); - cb->file_private = cl; - cb->major_file_operations = MEI_CLOSE; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; - if (mei_disconnect(dev, cl)) { - rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n"); - goto free; - } - mdelay(10); /* Wait for hardware disconnection ready */ - list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); - } else { - dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - - err = wait_event_timeout(dev->wait_recvd_msg, - (MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); - - mutex_lock(&dev->device_lock); - if (MEI_FILE_DISCONNECTED == cl->state) { - rets = 0; - dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n"); - } else { - rets = -ENODEV; - if (MEI_FILE_DISCONNECTED != cl->state) - dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n"); - - if (err) - dev_dbg(&dev->pdev->dev, - "wait failed disconnect err=%08x\n", - err); - - dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); - } - - mei_io_list_flush(&dev->ctrl_rd_list, cl); - mei_io_list_flush(&dev->ctrl_wr_list, cl); -free: - mei_free_cb_private(cb); - return rets; -} - -/** - * mei_remove_client_from_file_list - - * removes file private data from device file list - * - * @dev: the device structure - * @host_client_id: host client id to be removed - */ -void mei_remove_client_from_file_list(struct mei_device *dev, - u8 host_client_id) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (host_client_id == cl_pos->host_client_id) { - dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del_init(&cl_pos->link); - break; - } - } -} diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c deleted file mode 100644 index 9a2cfaf..0000000 --- a/drivers/staging/mei/interface.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include <linux/pci.h> -#include "mei_dev.h" -#include "mei.h" -#include "interface.h" - - - -/** - * mei_set_csr_register - writes H_CSR register to the mei device, - * and ignores the H_IS bit for it is write-one-to-zero. - * - * @dev: the device structure - */ -void mei_hcsr_set(struct mei_device *dev) -{ - if ((dev->host_hw_state & H_IS) == H_IS) - dev->host_hw_state &= ~H_IS; - mei_reg_write(dev, H_CSR, dev->host_hw_state); - dev->host_hw_state = mei_hcsr_read(dev); -} - -/** - * mei_csr_enable_interrupts - enables mei device interrupts - * - * @dev: the device structure - */ -void mei_enable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state |= H_IE; - mei_hcsr_set(dev); -} - -/** - * mei_csr_disable_interrupts - disables mei device interrupts - * - * @dev: the device structure - */ -void mei_disable_interrupts(struct mei_device *dev) -{ - dev->host_hw_state &= ~H_IE; - mei_hcsr_set(dev); -} - -/** - * _host_get_filled_slots - gets number of device filled buffer slots - * - * @device: the device structure - * - * returns number of filled slots - */ -static unsigned char _host_get_filled_slots(const struct mei_device *dev) -{ - char read_ptr, write_ptr; - - read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); - write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); - - return (unsigned char) (write_ptr - read_ptr); -} - -/** - * mei_host_buffer_is_empty - checks if host buffer is empty. - * - * @dev: the device structure - * - * returns 1 if empty, 0 - otherwise. - */ -int mei_host_buffer_is_empty(struct mei_device *dev) -{ - unsigned char filled_slots; - - dev->host_hw_state = mei_hcsr_read(dev); - filled_slots = _host_get_filled_slots(dev); - - if (filled_slots == 0) - return 1; - - return 0; -} - -/** - * mei_count_empty_write_slots - counts write empty slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count - */ -int mei_count_empty_write_slots(struct mei_device *dev) -{ - unsigned char buffer_depth, filled_slots, empty_slots; - - dev->host_hw_state = mei_hcsr_read(dev); - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - - /* check for overflow */ - if (filled_slots > buffer_depth) - return -EOVERFLOW; - - return empty_slots; -} - -/** - * mei_write_message - writes a message to mei device. - * - * @dev: the device structure - * @header: header of message - * @write_buffer: message buffer will be written - * @write_length: message size will be written - * - * This function returns -EIO if write has failed - */ -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length) -{ - u32 temp_msg = 0; - unsigned long bytes_written = 0; - unsigned char buffer_depth, filled_slots, empty_slots; - unsigned long dw_to_write; - - dev->host_hw_state = mei_hcsr_read(dev); - - dev_dbg(&dev->pdev->dev, - "host_hw_state = 0x%08x.\n", - dev->host_hw_state); - - dev_dbg(&dev->pdev->dev, - "mei_write_message header=%08x.\n", - *((u32 *) header)); - - buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); - filled_slots = _host_get_filled_slots(dev); - empty_slots = buffer_depth - filled_slots; - dev_dbg(&dev->pdev->dev, - "filled = %hu, empty = %hu.\n", - filled_slots, empty_slots); - - dw_to_write = ((write_length + 3) / 4); - - if (dw_to_write > empty_slots) - return -EIO; - - mei_reg_write(dev, H_CB_WW, *((u32 *) header)); - - while (write_length >= 4) { - mei_reg_write(dev, H_CB_WW, - *(u32 *) (write_buffer + bytes_written)); - bytes_written += 4; - write_length -= 4; - } - - if (write_length > 0) { - memcpy(&temp_msg, &write_buffer[bytes_written], write_length); - mei_reg_write(dev, H_CB_WW, temp_msg); - } - - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); - dev->me_hw_state = mei_mecsr_read(dev); - if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) - return -EIO; - - return 0; -} - -/** - * mei_count_full_read_slots - counts read full slots. - * - * @dev: the device structure - * - * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count - */ -int mei_count_full_read_slots(struct mei_device *dev) -{ - char read_ptr, write_ptr; - unsigned char buffer_depth, filled_slots; - - dev->me_hw_state = mei_mecsr_read(dev); - buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24); - read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8); - write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16); - filled_slots = (unsigned char) (write_ptr - read_ptr); - - /* check for overflow */ - if (filled_slots > buffer_depth) - return -EOVERFLOW; - - dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); - return (int)filled_slots; -} - -/** - * mei_read_slots - reads a message from mei device. - * - * @dev: the device structure - * @buffer: message buffer will be written - * @buffer_length: message size will be read - */ -void mei_read_slots(struct mei_device *dev, unsigned char *buffer, - unsigned long buffer_length) -{ - u32 *reg_buf = (u32 *)buffer; - - for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32)) - *reg_buf++ = mei_mecbrw_read(dev); - - if (buffer_length > 0) { - u32 reg = mei_mecbrw_read(dev); - memcpy(reg_buf, ®, buffer_length); - } - - dev->host_hw_state |= H_IG; - mei_hcsr_set(dev); -} - -/** - * mei_flow_ctrl_creds - checks flow_control credentials. - * - * @dev: the device structure - * @cl: private data of the file object - * - * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise. - * -ENOENT if mei_cl is not present - * -EINVAL if single_recv_buf == 0 - */ -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) -{ - int i; - - if (!dev->me_clients_num) - return 0; - - if (cl->mei_flow_ctrl_creds > 0) - return 1; - - for (i = 0; i < dev->me_clients_num; i++) { - struct mei_me_client *me_cl = &dev->me_clients[i]; - if (me_cl->client_id == cl->me_client_id) { - if (me_cl->mei_flow_ctrl_creds) { - if (WARN_ON(me_cl->props.single_recv_buf == 0)) - return -EINVAL; - return 1; - } else { - return 0; - } - } - } - return -ENOENT; -} - -/** - * mei_flow_ctrl_reduce - reduces flow_control. - * - * @dev: the device structure - * @cl: private data of the file object - * @returns - * 0 on success - * -ENOENT when me client is not found - * -EINVAL when ctrl credits are <= 0 - */ -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) -{ - int i; - - if (!dev->me_clients_num) - return -ENOENT; - - for (i = 0; i < dev->me_clients_num; i++) { - struct mei_me_client *me_cl = &dev->me_clients[i]; - if (me_cl->client_id == cl->me_client_id) { - if (me_cl->props.single_recv_buf != 0) { - if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) - return -EINVAL; - dev->me_clients[i].mei_flow_ctrl_creds--; - } else { - if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) - return -EINVAL; - cl->mei_flow_ctrl_creds--; - } - return 0; - } - } - return -ENOENT; -} - -/** - * mei_send_flow_control - sends flow control to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_flow_control *mei_flow_control; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_flow_control); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1]; - memset(mei_flow_control, 0, sizeof(*mei_flow_control)); - mei_flow_control->host_addr = cl->host_client_id; - mei_flow_control->me_addr = cl->me_client_id; - mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD; - memset(mei_flow_control->reserved, 0, - sizeof(mei_flow_control->reserved)); - dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_flow_control, - sizeof(struct hbm_flow_control)); -} - -/** - * mei_other_client_is_connecting - checks if other - * client with the same client id is connected. - * - * @dev: the device structure - * @cl: private data of the file object - * - * returns 1 if other client is connected, 0 - otherwise. - */ -int mei_other_client_is_connecting(struct mei_device *dev, - struct mei_cl *cl) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if ((cl_pos->state == MEI_FILE_CONNECTING) && - (cl_pos != cl) && - cl->me_client_id == cl_pos->me_client_id) - return 1; - - } - return 0; -} - -/** - * mei_disconnect - sends disconnect message to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_disconnect_request *mei_cli_disconnect; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_disconnect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_cli_disconnect = - (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1]; - memset(mei_cli_disconnect, 0, sizeof(*mei_cli_disconnect)); - mei_cli_disconnect->host_addr = cl->host_client_id; - mei_cli_disconnect->me_addr = cl->me_client_id; - mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; - mei_cli_disconnect->reserved[0] = 0; - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_disconnect, - sizeof(struct hbm_client_disconnect_request)); -} - -/** - * mei_connect - sends connect message to fw. - * - * @dev: the device structure - * @cl: private data of the file object - * - * This function returns -EIO on write failure - */ -int mei_connect(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_connect_request *mei_cli_connect; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_connect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_cli_connect = - (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; - mei_cli_connect->host_addr = cl->host_client_id; - mei_cli_connect->me_addr = cl->me_client_id; - mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD; - mei_cli_connect->reserved = 0; - - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_connect, - sizeof(struct hbm_client_connect_request)); -} diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h deleted file mode 100644 index fb90c6f..0000000 --- a/drivers/staging/mei/interface.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - - -#ifndef _MEI_INTERFACE_H_ -#define _MEI_INTERFACE_H_ - -#include "mei.h" -#include "mei_dev.h" - - -#define AMT_WD_DEFAULT_TIMEOUT 120 /* seconds */ -#define AMT_WD_MIN_TIMEOUT 120 /* seconds */ -#define AMT_WD_MAX_TIMEOUT 65535 /* seconds */ - -#define MEI_WATCHDOG_DATA_SIZE 16 -#define MEI_START_WD_DATA_SIZE 20 -#define MEI_WD_PARAMS_SIZE 4 - - -void mei_read_slots(struct mei_device *dev, - unsigned char *buffer, - unsigned long buffer_length); - -int mei_write_message(struct mei_device *dev, - struct mei_msg_hdr *header, - unsigned char *write_buffer, - unsigned long write_length); - -int mei_host_buffer_is_empty(struct mei_device *dev); - -int mei_count_full_read_slots(struct mei_device *dev); - -int mei_count_empty_write_slots(struct mei_device *dev); - -int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl); - -int mei_wd_send(struct mei_device *dev); -int mei_wd_stop(struct mei_device *dev, bool preserve); -bool mei_wd_host_init(struct mei_device *dev); -void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout); -/* - * mei_watchdog_register - Registering watchdog interface - * once we got connection to the WD Client - * @dev - mei device - */ -void mei_watchdog_register(struct mei_device *dev); -/* - * mei_watchdog_unregister - Unregistering watchdog interface - * @dev - mei device - */ -void mei_watchdog_unregister(struct mei_device *dev); - -int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl); - -int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl); - -int mei_disconnect(struct mei_device *dev, struct mei_cl *cl); -int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl); -int mei_connect(struct mei_device *dev, struct mei_cl *cl); - -#endif /* _MEI_INTERFACE_H_ */ diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c deleted file mode 100644 index 2007d24..0000000 --- a/drivers/staging/mei/interrupt.c +++ /dev/null @@ -1,1590 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - -#include <linux/pci.h> -#include <linux/kthread.h> -#include <linux/interrupt.h> -#include <linux/fs.h> -#include <linux/jiffies.h> - -#include "mei_dev.h" -#include "mei.h" -#include "hw.h" -#include "interface.h" - - -/** - * mei_interrupt_quick_handler - The ISR of the MEI device - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - */ -irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) -{ - struct mei_device *dev = (struct mei_device *) dev_id; - u32 csr_reg = mei_hcsr_read(dev); - - if ((csr_reg & H_IS) != H_IS) - return IRQ_NONE; - - /* clear H_IS bit in H_CSR */ - mei_reg_write(dev, H_CSR, csr_reg); - - return IRQ_WAKE_THREAD; -} - -/** - * _mei_cmpl - processes completed operation. - * - * @cl: private data of the file object. - * @cb_pos: callback block. - */ -static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) -{ - if (cb_pos->major_file_operations == MEI_WRITE) { - mei_free_cb_private(cb_pos); - cb_pos = NULL; - cl->writing_state = MEI_WRITE_COMPLETE; - if (waitqueue_active(&cl->tx_wait)) - wake_up_interruptible(&cl->tx_wait); - - } else if (cb_pos->major_file_operations == MEI_READ && - MEI_READING == cl->reading_state) { - cl->reading_state = MEI_READ_COMPLETE; - if (waitqueue_active(&cl->rx_wait)) - wake_up_interruptible(&cl->rx_wait); - - } -} - -/** - * _mei_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @cb_pos: callback block. - */ -static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) -{ - if (dev->iamthif_canceled != 1) { - dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; - dev->iamthif_stall_timer = 0; - memcpy(cb_pos->response_buffer.data, - dev->iamthif_msg_buf, - dev->iamthif_msg_buf_index); - list_add_tail(&cb_pos->cb_list, - &dev->amthi_read_complete_list.mei_cb.cb_list); - dev_dbg(&dev->pdev->dev, "amthi read completed.\n"); - dev->iamthif_timer = jiffies; - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", - dev->iamthif_timer); - } else { - mei_run_next_iamthif_cmd(dev); - } - - dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); - wake_up_interruptible(&dev->iamthif_cl.wait); -} - - -/** - * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to - * handle the read amthi message data processing. - * - * @complete_list: An instance of our list structure - * @dev: the device structure - * @mei_hdr: header of amthi message - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, - struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb; - unsigned char *buffer; - - BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); - BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); - - buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; - BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); - - mei_read_slots(dev, buffer, mei_hdr->length); - - dev->iamthif_msg_buf_index += mei_hdr->length; - - if (!mei_hdr->msg_complete) - return 0; - - dev_dbg(&dev->pdev->dev, - "amthi_message_buffer_index =%d\n", - mei_hdr->length); - - dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); - if (!dev->iamthif_current_cb) - return -ENODEV; - - cb = dev->iamthif_current_cb; - dev->iamthif_current_cb = NULL; - - cl = (struct mei_cl *)cb->file_private; - if (!cl) - return -ENODEV; - - dev->iamthif_stall_timer = 0; - cb->information = dev->iamthif_msg_buf_index; - cb->read_time = jiffies; - if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { - /* found the iamthif cb */ - dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); - dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); - list_add_tail(&cb->cb_list, - &complete_list->mei_cb.cb_list); - } - return 0; -} - -/** - * _mei_irq_thread_state_ok - checks if mei header matches file private data - * - * @cl: private data of the file object - * @mei_hdr: header of mei client message - * - * returns !=0 if matches, 0 if no match. - */ -static int _mei_irq_thread_state_ok(struct mei_cl *cl, - struct mei_msg_hdr *mei_hdr) -{ - return (cl->host_client_id == mei_hdr->host_addr && - cl->me_client_id == mei_hdr->me_addr && - cl->state == MEI_FILE_CONNECTED && - MEI_READ_COMPLETE != cl->reading_state); -} - -/** - * mei_irq_thread_read_client_message - bottom half read routine after ISR to - * handle the read mei client message data processing. - * - * @complete_list: An instance of our list structure - * @dev: the device structure - * @mei_hdr: header of mei client message - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, - struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - unsigned char *buffer = NULL; - - dev_dbg(&dev->pdev->dev, "start client msg\n"); - if (list_empty(&dev->read_list.mei_cb.cb_list)) - goto quit; - - list_for_each_entry_safe(cb_pos, cb_next, - &dev->read_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { - cl->reading_state = MEI_READING; - buffer = cb_pos->response_buffer.data + cb_pos->information; - - if (cb_pos->response_buffer.size < - mei_hdr->length + cb_pos->information) { - dev_dbg(&dev->pdev->dev, "message overflow.\n"); - list_del(&cb_pos->cb_list); - return -ENOMEM; - } - if (buffer) - mei_read_slots(dev, buffer, mei_hdr->length); - - cb_pos->information += mei_hdr->length; - if (mei_hdr->msg_complete) { - cl->status = 0; - list_del(&cb_pos->cb_list); - dev_dbg(&dev->pdev->dev, - "completed read host client = %d," - "ME client = %d, " - "data length = %lu\n", - cl->host_client_id, - cl->me_client_id, - cb_pos->information); - - *(cb_pos->response_buffer.data + - cb_pos->information) = '\0'; - dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n", - cb_pos->response_buffer.data); - list_add_tail(&cb_pos->cb_list, - &complete_list->mei_cb.cb_list); - } - - break; - } - - } - -quit: - dev_dbg(&dev->pdev->dev, "message read\n"); - if (!buffer) { - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n", - *(u32 *) dev->rd_msg_buf); - } - - return 0; -} - -/** - * _mei_irq_thread_iamthif_read - prepares to read iamthif data. - * - * @dev: the device structure. - * @slots: free slots. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) -{ - - if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) - + sizeof(struct hbm_flow_control))) { - return -EMSGSIZE; - } - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (mei_send_flow_control(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); - return -EIO; - } - - dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); - dev->iamthif_state = MEI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = false; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); - return 0; -} - -/** - * _mei_irq_thread_close - processes close related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_disconnect_request))) { - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_disconnect_request) + 3) / 4; - - if (mei_disconnect(dev, cl)) { - cl->status = 0; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -EMSGSIZE; - } else { - cl->state = MEI_FILE_DISCONNECTING; - cl->status = 0; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); - cl->timer_count = MEI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - return -EBADMSG; - } - - return 0; -} - -/** - * is_treat_specially_client - checks if the message belongs - * to the file private data. - * - * @cl: private data of the file object - * @rs: connect response bus message - * - */ -static bool is_treat_specially_client(struct mei_cl *cl, - struct hbm_client_connect_response *rs) -{ - - if (cl->host_client_id == rs->host_addr && - cl->me_client_id == rs->me_addr) { - if (!rs->status) { - cl->state = MEI_FILE_CONNECTED; - cl->status = 0; - - } else { - cl->state = MEI_FILE_DISCONNECTED; - cl->status = -ENODEV; - } - cl->timer_count = 0; - - return true; - } - return false; -} - -/** - * mei_client_connect_response - connects to response irq routine - * - * @dev: the device structure - * @rs: connect response bus message - */ -static void mei_client_connect_response(struct mei_device *dev, - struct hbm_client_connect_response *rs) -{ - - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - - dev_dbg(&dev->pdev->dev, - "connect_response:\n" - "ME Client = %d\n" - "Host Client = %d\n" - "Status = %d\n", - rs->me_addr, - rs->host_addr, - rs->status); - - /* if WD or iamthif client treat specially */ - - if (is_treat_specially_client(&(dev->wd_cl), rs)) { - dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); - mei_watchdog_register(dev); - - /* next step in the state maching */ - mei_host_init_iamthif(dev); - return; - } - - if (is_treat_specially_client(&(dev->iamthif_cl), rs)) { - dev->iamthif_state = MEI_IAMTHIF_IDLE; - return; - } - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { - - cl = (struct mei_cl *)cb_pos->file_private; - if (!cl) { - list_del(&cb_pos->cb_list); - return; - } - if (MEI_IOCTL == cb_pos->major_file_operations) { - if (is_treat_specially_client(cl, rs)) { - list_del(&cb_pos->cb_list); - cl->status = 0; - cl->timer_count = 0; - break; - } - } - } -} - -/** - * mei_client_disconnect_response - disconnects from response irq routine - * - * @dev: the device structure - * @rs: disconnect response bus message - */ -static void mei_client_disconnect_response(struct mei_device *dev, - struct hbm_client_connect_response *rs) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - - dev_dbg(&dev->pdev->dev, - "disconnect_response:\n" - "ME Client = %d\n" - "Host Client = %d\n" - "Status = %d\n", - rs->me_addr, - rs->host_addr, - rs->status); - - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - - if (!cl) { - list_del(&cb_pos->cb_list); - return; - } - - dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n"); - if (cl->host_client_id == rs->host_addr && - cl->me_client_id == rs->me_addr) { - - list_del(&cb_pos->cb_list); - if (!rs->status) - cl->state = MEI_FILE_DISCONNECTED; - - cl->status = 0; - cl->timer_count = 0; - break; - } - } -} - -/** - * same_flow_addr - tells if they have the same address. - * - * @file: private data of the file object. - * @flow: flow control. - * - * returns !=0, same; 0,not. - */ -static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow) -{ - return (cl->host_client_id == flow->host_addr && - cl->me_client_id == flow->me_addr); -} - -/** - * add_single_flow_creds - adds single buffer credentials. - * - * @file: private data ot the file object. - * @flow: flow control. - */ -static void add_single_flow_creds(struct mei_device *dev, - struct hbm_flow_control *flow) -{ - struct mei_me_client *client; - int i; - - for (i = 0; i < dev->me_clients_num; i++) { - client = &dev->me_clients[i]; - if (client && flow->me_addr == client->client_id) { - if (client->props.single_recv_buf) { - client->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", - flow->me_addr); - dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", - client->mei_flow_ctrl_creds); - } else { - BUG(); /* error in flow control */ - } - } - } -} - -/** - * mei_client_flow_control_response - flow control response irq routine - * - * @dev: the device structure - * @flow_control: flow control response bus message - */ -static void mei_client_flow_control_response(struct mei_device *dev, - struct hbm_flow_control *flow_control) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - if (!flow_control->host_addr) { - /* single receive buffer */ - add_single_flow_creds(dev, flow_control); - } else { - /* normal connection */ - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n"); - - dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - if (same_flow_addr(cl_pos, flow_control)) { - dev_dbg(&dev->pdev->dev, "recv ctrl msg for host %d ME %d.\n", - flow_control->host_addr, - flow_control->me_addr); - cl_pos->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", - cl_pos->mei_flow_ctrl_creds); - break; - } - } - } -} - -/** - * same_disconn_addr - tells if they have the same address - * - * @file: private data of the file object. - * @disconn: disconnection request. - * - * returns !=0, same; 0,not. - */ -static int same_disconn_addr(struct mei_cl *cl, - struct hbm_client_disconnect_request *disconn) -{ - return (cl->host_client_id == disconn->host_addr && - cl->me_client_id == disconn->me_addr); -} - -/** - * mei_client_disconnect_request - disconnects from request irq routine - * - * @dev: the device structure. - * @disconnect_req: disconnect request bus message. - */ -static void mei_client_disconnect_request(struct mei_device *dev, - struct hbm_client_disconnect_request *disconnect_req) -{ - struct mei_msg_hdr *mei_hdr; - struct hbm_client_connect_response *disconnect_res; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (same_disconn_addr(cl_pos, disconnect_req)) { - dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", - disconnect_req->host_addr, - disconnect_req->me_addr); - cl_pos->state = MEI_FILE_DISCONNECTED; - cl_pos->timer_count = 0; - if (cl_pos == &dev->wd_cl) { - dev->wd_due_counter = 0; - dev->wd_pending = false; - } else if (cl_pos == &dev->iamthif_cl) - dev->iamthif_timer = 0; - - /* prepare disconnect response */ - mei_hdr = - (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = - sizeof(struct hbm_client_connect_response); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - disconnect_res = - (struct hbm_client_connect_response *) - &dev->ext_msg_buf[1]; - disconnect_res->host_addr = cl_pos->host_client_id; - disconnect_res->me_addr = cl_pos->me_client_id; - disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; - disconnect_res->status = 0; - dev->extra_write_index = 2; - break; - } - } -} - - -/** - * mei_irq_thread_read_bus_message - bottom half read routine after ISR to - * handle the read bus message cmd processing. - * - * @dev: the device structure - * @mei_hdr: header of bus message - */ -static void mei_irq_thread_read_bus_message(struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_bus_message *mei_msg; - struct hbm_host_version_response *version_res; - struct hbm_client_connect_response *connect_res; - struct hbm_client_connect_response *disconnect_res; - struct hbm_flow_control *flow_control; - struct hbm_props_response *props_res; - struct hbm_host_enum_response *enum_res; - struct hbm_client_disconnect_request *disconnect_req; - struct hbm_host_stop_request *host_stop_req; - int res; - - - /* read the message to our buffer */ - BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); - mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; - - switch (mei_msg->hbm_cmd) { - case HOST_START_RES_CMD: - version_res = (struct hbm_host_version_response *) mei_msg; - if (version_res->host_version_supported) { - dev->version.major_version = HBM_MAJOR_VERSION; - dev->version.minor_version = HBM_MINOR_VERSION; - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == MEI_START_MESSAGE) { - dev->init_clients_timer = 0; - mei_host_enum_clients_message(dev); - } else { - dev->recvd_msg = false; - dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); - mei_reset(dev, 1); - return; - } - } else { - dev->version = version_res->me_max_version; - /* send stop message */ - mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_stop_req = (struct hbm_host_stop_request *) - &dev->wr_msg_buf[1]; - - memset(host_stop_req, - 0, - sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - mei_write_message(dev, mei_hdr, - (unsigned char *) (host_stop_req), - mei_hdr->length); - dev_dbg(&dev->pdev->dev, "version mismatch.\n"); - return; - } - - dev->recvd_msg = true; - dev_dbg(&dev->pdev->dev, "host start response message received.\n"); - break; - - case CLIENT_CONNECT_RES_CMD: - connect_res = - (struct hbm_client_connect_response *) mei_msg; - mei_client_connect_response(dev, connect_res); - dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case CLIENT_DISCONNECT_RES_CMD: - disconnect_res = - (struct hbm_client_connect_response *) mei_msg; - mei_client_disconnect_response(dev, disconnect_res); - dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); - wake_up(&dev->wait_recvd_msg); - break; - - case MEI_FLOW_CONTROL_CMD: - flow_control = (struct hbm_flow_control *) mei_msg; - mei_client_flow_control_response(dev, flow_control); - dev_dbg(&dev->pdev->dev, "client flow control response message received.\n"); - break; - - case HOST_CLIENT_PROPERTIES_RES_CMD: - props_res = (struct hbm_props_response *)mei_msg; - if (props_res->status || !dev->me_clients) { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); - mei_reset(dev, 1); - return; - } - if (dev->me_clients[dev->me_client_presentation_num] - .client_id == props_res->address) { - - dev->me_clients[dev->me_client_presentation_num].props - = props_res->client_properties; - - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == - MEI_CLIENT_PROPERTIES_MESSAGE) { - dev->me_client_index++; - dev->me_client_presentation_num++; - - /** Send Client Properties request **/ - res = mei_host_client_properties(dev); - if (res < 0) { - dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); - return; - } else if (!res) { - /* - * No more clients to send to. - * Clear Map for indicating now ME clients - * with associated host client - */ - bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); - dev->open_handle_count = 0; - - /* - * Reserving the first three client IDs - * Client Id 0 - Reserved for MEI Bus Message communications - * Client Id 1 - Reserved for Watchdog - * Client ID 2 - Reserved for AMTHI - */ - bitmap_set(dev->host_clients_map, 0, 3); - dev->mei_state = MEI_ENABLED; - - /* if wd initialization fails, initialization the AMTHI client, - * otherwise the AMTHI client will be initialized after the WD client connect response - * will be received - */ - if (mei_wd_host_init(dev)) - mei_host_init_iamthif(dev); - } - - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); - mei_reset(dev, 1); - return; - } - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); - mei_reset(dev, 1); - return; - } - break; - - case HOST_ENUM_RES_CMD: - enum_res = (struct hbm_host_enum_response *) mei_msg; - memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); - if (dev->mei_state == MEI_INIT_CLIENTS && - dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) { - dev->init_clients_timer = 0; - dev->me_client_presentation_num = 0; - dev->me_client_index = 0; - mei_allocate_me_clients_storage(dev); - dev->init_clients_state = - MEI_CLIENT_PROPERTIES_MESSAGE; - mei_host_client_properties(dev); - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); - mei_reset(dev, 1); - return; - } - break; - - case HOST_STOP_RES_CMD: - dev->mei_state = MEI_DISABLED; - dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n"); - mei_reset(dev, 1); - break; - - case CLIENT_DISCONNECT_REQ_CMD: - /* search for client */ - disconnect_req = - (struct hbm_client_disconnect_request *) mei_msg; - mei_client_disconnect_request(dev, disconnect_req); - break; - - case ME_STOP_REQ_CMD: - /* prepare stop request */ - mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - host_stop_req = - (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; - memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - host_stop_req->reserved[0] = 0; - host_stop_req->reserved[1] = 0; - dev->extra_write_index = 2; - break; - - default: - BUG(); - break; - - } -} - - -/** - * _mei_hb_read - processes read related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control))) { - /* return the cancel routine */ - list_del(&cb_pos->cb_list); - return -EBADMSG; - } - - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_flow_control) + 3) / 4; - if (mei_send_flow_control(dev, cl)) { - cl->status = -ENODEV; - cb_pos->information = 0; - list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } - list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); - - return 0; -} - - -/** - * _mei_irq_thread_ioctl - processes ioctl related operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request))) { - cl->state = MEI_FILE_CONNECTING; - *slots -= (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_connect_request) + 3) / 4; - if (mei_connect(dev, cl)) { - cl->status = -ENODEV; - cb_pos->information = 0; - list_del(&cb_pos->cb_list); - return -ENODEV; - } else { - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); - cl->timer_count = MEI_CONNECT_TIMEOUT; - } - } else { - /* return the cancel routine */ - list_del(&cb_pos->cb_list); - return -EBADMSG; - } - - return 0; -} - -/** - * _mei_irq_thread_cmpl - processes completed and no-iamthif operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - struct mei_msg_hdr *mei_hdr; - - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - (cb_pos->request_buffer.size - - cb_pos->information))) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = cb_pos->request_buffer.size - - cb_pos->information; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" - "mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->information), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - cl->status = 0; - cb_pos->information += mei_hdr->length; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - - (*slots) -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->information), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); - return -ENODEV; - } else { - cb_pos->information += mei_hdr->length; - dev_dbg(&dev->pdev->dev, - "cb_pos->request_buffer.size =%d" - " mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - } - return -EMSGSIZE; - } else { - return -EBADMSG; - } - - return 0; -} - -/** - * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_io_list *cmpl_list) -{ - struct mei_msg_hdr *mei_hdr; - - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index)) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - dev->iamthif_state = MEI_IAMTHIF_IDLE; - cl->status = -ENODEV; - list_del(&cb_pos->cb_list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - dev->iamthif_msg_buf_index += mei_hdr->length; - cb_pos->information = dev->iamthif_msg_buf_index; - cl->status = 0; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = true; - /* save iamthif cb sent to amthi client */ - dev->iamthif_current_cb = cb_pos; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - - } - } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - - *slots -= (sizeof(struct mei_msg_hdr) + - mei_hdr->length + 3) / 4; - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - cl->status = -ENODEV; - list_del(&cb_pos->cb_list); - } else { - dev->iamthif_msg_buf_index += mei_hdr->length; - } - return -EMSGSIZE; - } else { - return -EBADMSG; - } - - return 0; -} - -/** - * mei_irq_thread_read_handler - bottom half read routine after ISR to - * handle the read processing. - * - * @cmpl_list: An instance of our list structure - * @dev: the device structure - * @slots: slots to read. - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list, - struct mei_device *dev, - s32 *slots) -{ - struct mei_msg_hdr *mei_hdr; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - int ret = 0; - - if (!dev->rd_msg_hdr) { - dev->rd_msg_hdr = mei_mecbrw_read(dev); - dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); - (*slots)--; - dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); - } - mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); - - if (mei_hdr->reserved || !dev->rd_msg_hdr) { - dev_dbg(&dev->pdev->dev, "corrupted message header.\n"); - ret = -EBADMSG; - goto end; - } - - if (mei_hdr->host_addr || mei_hdr->me_addr) { - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - dev_dbg(&dev->pdev->dev, - "list_for_each_entry_safe read host" - " client = %d, ME client = %d\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - if (cl_pos->host_client_id == mei_hdr->host_addr && - cl_pos->me_client_id == mei_hdr->me_addr) - break; - } - - if (&cl_pos->link == &dev->file_list) { - dev_dbg(&dev->pdev->dev, "corrupted message header\n"); - ret = -EBADMSG; - goto end; - } - } - if (((*slots) * sizeof(u32)) < mei_hdr->length) { - dev_dbg(&dev->pdev->dev, - "we can't read the message slots =%08x.\n", - *slots); - /* we can't read the message */ - ret = -ERANGE; - goto end; - } - - /* decide where to read the message too */ - if (!mei_hdr->host_addr) { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); - mei_irq_thread_read_bus_message(dev, mei_hdr); - dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); - } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && - (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && - (dev->iamthif_state == MEI_IAMTHIF_READING)) { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - ret = mei_irq_thread_read_amthi_message(cmpl_list, - dev, mei_hdr); - if (ret) - goto end; - - } else { - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n"); - ret = mei_irq_thread_read_client_message(cmpl_list, - dev, mei_hdr); - if (ret) - goto end; - - } - - /* reset the number of slots and header */ - *slots = mei_count_full_read_slots(dev); - dev->rd_msg_hdr = 0; - - if (*slots == -EOVERFLOW) { - /* overflow - reset */ - dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n"); - /* set the event since message has been read */ - ret = -ERANGE; - goto end; - } -end: - return ret; -} - - -/** - * mei_irq_thread_write_handler - bottom half write routine after - * ISR to handle the write processing. - * - * @cmpl_list: An instance of our list structure - * @dev: the device structure - * @slots: slots to write. - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, - struct mei_device *dev, - s32 *slots) -{ - - struct mei_cl *cl; - struct mei_cl_cb *pos = NULL, *next = NULL; - struct mei_io_list *list; - int ret; - - if (!mei_host_buffer_is_empty(dev)) { - dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); - return 0; - } - *slots = mei_count_empty_write_slots(dev); - /* complete all waiting for write CB */ - dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); - - list = &dev->write_waiting_list; - list_for_each_entry_safe(pos, next, - &list->mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)pos->file_private; - if (cl == NULL) - continue; - - cl->status = 0; - list_del(&pos->cb_list); - if (MEI_WRITING == cl->writing_state && - (pos->major_file_operations == MEI_WRITE) && - (cl != &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, - "MEI WRITE COMPLETE\n"); - cl->writing_state = MEI_WRITE_COMPLETE; - list_add_tail(&pos->cb_list, - &cmpl_list->mei_cb.cb_list); - } - if (cl == &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); - if (dev->iamthif_flow_control_pending) { - ret = _mei_irq_thread_iamthif_read( - dev, slots); - if (ret) - return ret; - } - } - } - - if (dev->stop && !dev->wd_pending) { - dev->wd_stopped = true; - wake_up_interruptible(&dev->wait_stop_wd); - return 0; - } - - if (dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n", - dev->extra_write_index); - mei_write_message(dev, - (struct mei_msg_hdr *) &dev->ext_msg_buf[0], - (unsigned char *) &dev->ext_msg_buf[1], - (dev->extra_write_index - 1) * sizeof(u32)); - *slots -= dev->extra_write_index; - dev->extra_write_index = 0; - } - if (dev->mei_state == MEI_ENABLED) { - if (dev->wd_pending && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { - if (mei_wd_send(dev)) - dev_dbg(&dev->pdev->dev, "wd send failed.\n"); - else - if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) - return -ENODEV; - - dev->wd_pending = false; - - if (dev->wd_timeout) { - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_START_WD_DATA_SIZE + 3) / 4; - dev->wd_due_counter = 2; - } else { - *slots -= (sizeof(struct mei_msg_hdr) + - MEI_WD_PARAMS_SIZE + 3) / 4; - dev->wd_due_counter = 0; - } - - } - } - if (dev->stop) - return -ENODEV; - - /* complete control write list CB */ - dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *) pos->file_private; - if (!cl) { - list_del(&pos->cb_list); - return -ENODEV; - } - switch (pos->major_file_operations) { - case MEI_CLOSE: - /* send disconnect message */ - ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - case MEI_READ: - /* send flow control message */ - ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - case MEI_IOCTL: - /* connect message */ - if (mei_other_client_is_connecting(dev, cl)) - continue; - ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list); - if (ret) - return ret; - - break; - - default: - BUG(); - } - - } - /* complete write list CB */ - dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->write_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)pos->file_private; - if (cl == NULL) - continue; - - if (cl != &dev->iamthif_cl) { - if (!mei_flow_ctrl_creds(dev, cl)) { - dev_dbg(&dev->pdev->dev, - "No flow control" - " credentials for client" - " %d, not sending.\n", - cl->host_client_id); - continue; - } - ret = _mei_irq_thread_cmpl(dev, slots, - pos, - cl, cmpl_list); - if (ret) - return ret; - - } else if (cl == &dev->iamthif_cl) { - /* IAMTHIF IOCTL */ - dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); - if (!mei_flow_ctrl_creds(dev, cl)) { - dev_dbg(&dev->pdev->dev, - "No flow control" - " credentials for amthi" - " client %d.\n", - cl->host_client_id); - continue; - } - ret = _mei_irq_thread_cmpl_iamthif(dev, - slots, - pos, - cl, - cmpl_list); - if (ret) - return ret; - - } - - } - return 0; -} - - - -/** - * mei_timer - timer function. - * - * @work: pointer to the work_struct structure - * - * NOTE: This function is called by timer interrupt work - */ -void mei_timer(struct work_struct *work) -{ - unsigned long timeout; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - struct list_head *amthi_complete_list = NULL; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - - struct mei_device *dev = container_of(work, - struct mei_device, timer_work.work); - - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - if (dev->mei_state == MEI_INIT_CLIENTS) { - if (dev->init_clients_timer) { - if (--dev->init_clients_timer == 0) { - dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n", - dev->init_clients_state); - mei_reset(dev, 1); - } - } - } - goto out; - } - /*** connect/disconnect timeouts ***/ - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (cl_pos->timer_count) { - if (--cl_pos->timer_count == 0) { - dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n"); - mei_reset(dev, 1); - goto out; - } - } - } - - if (dev->iamthif_stall_timer) { - if (--dev->iamthif_stall_timer == 0) { - dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n"); - mei_reset(dev, 1); - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); - - dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; - mei_run_next_iamthif_cmd(dev); - } - } - - if (dev->iamthif_timer) { - - timeout = dev->iamthif_timer + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", - dev->iamthif_timer); - dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); - dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); - if (time_after(jiffies, timeout)) { - /* - * User didn't read the AMTHI data on time (15sec) - * freeing AMTHI for other requests - */ - - dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); - - amthi_complete_list = &dev->amthi_read_complete_list. - mei_cb.cb_list; - - list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) { - - cl_pos = cb_pos->file_object->private_data; - - /* Finding the AMTHI entry. */ - if (cl_pos == &dev->iamthif_cl) - list_del(&cb_pos->cb_list); - } - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); - - dev->iamthif_file_object->private_data = NULL; - dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; - dev->iamthif_timer = 0; - mei_run_next_iamthif_cmd(dev); - - } - } -out: - schedule_delayed_work(&dev->timer_work, 2 * HZ); - mutex_unlock(&dev->device_lock); -} - -/** - * mei_interrupt_thread_handler - function called after ISR to handle the interrupt - * processing. - * - * @irq: The irq number - * @dev_id: pointer to the device structure - * - * returns irqreturn_t - * - */ -irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) -{ - struct mei_device *dev = (struct mei_device *) dev_id; - struct mei_io_list complete_list; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - struct mei_cl *cl; - s32 slots; - int rets; - bool bus_message_received; - - - dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); - /* initialize our complete list */ - mutex_lock(&dev->device_lock); - mei_io_list_init(&complete_list); - dev->host_hw_state = mei_hcsr_read(dev); - - /* Ack the interrupt here - * In case of MSI we don't go through the quick handler */ - if (pci_dev_msi_enabled(dev->pdev)) - mei_reg_write(dev, H_CSR, dev->host_hw_state); - - dev->me_hw_state = mei_mecsr_read(dev); - - /* check if ME wants a reset */ - if ((dev->me_hw_state & ME_RDY_HRA) == 0 && - dev->mei_state != MEI_RESETING && - dev->mei_state != MEI_INITIALIZING) { - dev_dbg(&dev->pdev->dev, "FW not ready.\n"); - mei_reset(dev, 1); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } - - /* check if we need to start the dev */ - if ((dev->host_hw_state & H_RDY) == 0) { - if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { - dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); - dev->host_hw_state |= (H_IE | H_IG | H_RDY); - mei_hcsr_set(dev); - dev->mei_state = MEI_INIT_CLIENTS; - dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); - /* link is established - * start sending messages. - */ - mei_host_start_message(dev); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } else { - dev_dbg(&dev->pdev->dev, "FW not ready.\n"); - mutex_unlock(&dev->device_lock); - return IRQ_HANDLED; - } - } - /* check slots available for reading */ - slots = mei_count_full_read_slots(dev); - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - while (slots > 0 && !dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); - rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); - if (rets) - goto end; - } - rets = mei_irq_thread_write_handler(&complete_list, dev, &slots); -end: - dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); - dev->host_hw_state = mei_hcsr_read(dev); - dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev); - - bus_message_received = false; - if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) { - dev_dbg(&dev->pdev->dev, "received waiting bus message\n"); - bus_message_received = true; - } - mutex_unlock(&dev->device_lock); - if (bus_message_received) { - dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n"); - wake_up_interruptible(&dev->wait_recvd_msg); - bus_message_received = false; - } - if (list_empty(&complete_list.mei_cb.cb_list)) - return IRQ_HANDLED; - - - list_for_each_entry_safe(cb_pos, cb_next, - &complete_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; - list_del(&cb_pos->cb_list); - if (cl) { - if (cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "completing call back.\n"); - _mei_cmpl(cl, cb_pos); - cb_pos = NULL; - } else if (cl == &dev->iamthif_cl) { - _mei_cmpl_iamthif(dev, cb_pos); - } - } - } - return IRQ_HANDLED; -} diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c deleted file mode 100644 index 0a80dc4..0000000 --- a/drivers/staging/mei/iorw.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/aio.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ioctl.h> -#include <linux/cdev.h> -#include <linux/list.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/uuid.h> -#include <linux/jiffies.h> -#include <linux/uaccess.h> - - -#include "mei_dev.h" -#include "hw.h" -#include "mei.h" -#include "interface.h" - - - -/** - * mei_ioctl_connect_client - the connect to fw client IOCTL function - * - * @dev: the device structure - * @data: IOCTL connect data, input and output parameters - * @file: private data of the file object - * - * Locking: called under "dev->device_lock" lock - * - * returns 0 on success, <0 on failure. - */ -int mei_ioctl_connect_client(struct file *file, - struct mei_connect_client_data *data) -{ - struct mei_device *dev; - struct mei_cl_cb *cb; - struct mei_client *client; - struct mei_cl *cl; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - long timeout = CONNECT_TIMEOUT; - int i; - int err; - int rets; - - cl = file->private_data; - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n"); - - - /* buffered ioctl cb */ - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) { - rets = -ENOMEM; - goto end; - } - INIT_LIST_HEAD(&cb->cb_list); - - cb->major_file_operations = MEI_IOCTL; - - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto end; - } - if (cl->state != MEI_FILE_INITIALIZING && - cl->state != MEI_FILE_DISCONNECTED) { - rets = -EBUSY; - goto end; - } - - /* find ME client we're trying to connect to */ - i = mei_find_me_client_index(dev, data->in_client_uuid); - if (i >= 0 && !dev->me_clients[i].props.fixed_address) { - cl->me_client_id = dev->me_clients[i].client_id; - cl->state = MEI_FILE_CONNECTING; - } - - dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", - cl->me_client_id); - dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", - dev->me_clients[i].props.protocol_version); - dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", - dev->me_clients[i].props.max_msg_length); - - /* if we're connecting to amthi client then we will use the - * existing connection - */ - if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) { - dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); - if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - goto end; - } - clear_bit(cl->host_client_id, dev->host_clients_map); - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - if (mei_cl_cmp_id(cl, cl_pos)) { - dev_dbg(&dev->pdev->dev, - "remove file private data node host" - " client = %d, ME client = %d.\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del(&cl_pos->link); - } - - } - dev_dbg(&dev->pdev->dev, "free file private data memory.\n"); - kfree(cl); - - cl = NULL; - file->private_data = &dev->iamthif_cl; - - client = &data->out_client_properties; - client->max_msg_length = - dev->me_clients[i].props.max_msg_length; - client->protocol_version = - dev->me_clients[i].props.protocol_version; - rets = dev->iamthif_cl.status; - - goto end; - } - - if (cl->state != MEI_FILE_CONNECTING) { - rets = -ENODEV; - goto end; - } - - - /* prepare the output buffer */ - client = &data->out_client_properties; - client->max_msg_length = dev->me_clients[i].props.max_msg_length; - client->protocol_version = dev->me_clients[i].props.protocol_version; - dev_dbg(&dev->pdev->dev, "Can connect?\n"); - if (dev->mei_host_buffer_is_empty - && !mei_other_client_is_connecting(dev, cl)) { - dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); - dev->mei_host_buffer_is_empty = false; - if (mei_connect(dev, cl)) { - dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); - rets = -ENODEV; - goto end; - } else { - dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n"); - cl->timer_count = MEI_CONNECT_TIMEOUT; - cb->file_private = cl; - list_add_tail(&cb->cb_list, - &dev->ctrl_rd_list.mei_cb. - cb_list); - } - - - } else { - dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n"); - cb->file_private = cl; - dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - err = wait_event_timeout(dev->wait_recvd_msg, - (MEI_FILE_CONNECTED == cl->state || - MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); - - mutex_lock(&dev->device_lock); - if (MEI_FILE_CONNECTED == cl->state) { - dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n"); - rets = cl->status; - goto end; - } else { - dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n", - cl->state); - if (!err) { - dev_dbg(&dev->pdev->dev, - "wait_event_interruptible_timeout failed on client" - " connect message fw response message.\n"); - } - rets = -EFAULT; - - mei_io_list_flush(&dev->ctrl_rd_list, cl); - mei_io_list_flush(&dev->ctrl_wr_list, cl); - goto end; - } - rets = 0; -end: - dev_dbg(&dev->pdev->dev, "free connect cb memory."); - kfree(cb); - return rets; -} - -/** - * find_amthi_read_list_entry - finds a amthilist entry for current file - * - * @dev: the device structure - * @file: pointer to file object - * - * returns returned a list entry on success, NULL on failure. - */ -struct mei_cl_cb *find_amthi_read_list_entry( - struct mei_device *dev, - struct file *file) -{ - struct mei_cl *cl_temp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - list_for_each_entry_safe(pos, next, - &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) { - cl_temp = (struct mei_cl *)pos->file_private; - if (cl_temp && cl_temp == &dev->iamthif_cl && - pos->file_object == file) - return pos; - } - return NULL; -} - -/** - * amthi_read - read data from AMTHI client - * - * @dev: the device structure - * @if_num: minor number - * @file: pointer to file object - * @*ubuf: pointer to user data in user space - * @length: data length to read - * @offset: data read offset - * - * Locking: called under "dev->device_lock" lock - * - * returns - * returned data length on success, - * zero if no data to read, - * negative on failure. - */ -int amthi_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset) -{ - int rets; - int wait_ret; - struct mei_cl_cb *cb = NULL; - struct mei_cl *cl = file->private_data; - unsigned long timeout; - int i; - - /* Only Posible if we are in timeout */ - if (!cl || cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "bad file ext.\n"); - return -ETIMEDOUT; - } - - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_cl.me_client_id) - break; - } - - if (i == dev->me_clients_num) { - dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); - return -ENODEV; - } - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "checking amthi data\n"); - cb = find_amthi_read_list_entry(dev, file); - - /* Check for if we can block or not*/ - if (cb == NULL && file->f_flags & O_NONBLOCK) - return -EAGAIN; - - - dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); - while (cb == NULL) { - /* unlock the Mutex */ - mutex_unlock(&dev->device_lock); - - wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, - (cb = find_amthi_read_list_entry(dev, file))); - - if (wait_ret) - return -ERESTARTSYS; - - dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); - - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); - } - - - dev_dbg(&dev->pdev->dev, "Got amthi data\n"); - dev->iamthif_timer = 0; - - if (cb) { - timeout = cb->read_time + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", - timeout); - - if (time_after(jiffies, timeout)) { - dev_dbg(&dev->pdev->dev, "amthi Time out\n"); - /* 15 sec for the message has expired */ - list_del(&cb->cb_list); - rets = -ETIMEDOUT; - goto free; - } - } - /* if the whole message will fit remove it from the list */ - if (cb->information >= *offset && length >= (cb->information - *offset)) - list_del(&cb->cb_list); - else if (cb->information > 0 && cb->information <= *offset) { - /* end of the message has been reached */ - list_del(&cb->cb_list); - rets = 0; - goto free; - } - /* else means that not full buffer will be read and do not - * remove message from deletion list - */ - - dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", - cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n", - cb->information); - - /* length is being turncated to PAGE_SIZE, however, - * the information may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); - - if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) - rets = -EFAULT; - else { - rets = length; - if ((*offset + length) < cb->information) { - *offset += length; - goto out; - } - } -free: - dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); - *offset = 0; - mei_free_cb_private(cb); -out: - return rets; -} - -/** - * mei_start_read - the start read client message function. - * - * @dev: the device structure - * @if_num: minor number - * @cl: private data of the file object - * - * returns 0 on success, <0 on failure. - */ -int mei_start_read(struct mei_device *dev, struct mei_cl *cl) -{ - struct mei_cl_cb *cb; - int rets = 0; - int i; - - if (cl->state != MEI_FILE_CONNECTED) - return -ENODEV; - - if (dev->mei_state != MEI_ENABLED) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "check if read is pending.\n"); - if (cl->read_pending || cl->read_cb) { - dev_dbg(&dev->pdev->dev, "read is pending.\n"); - return -EBUSY; - } - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return -ENOMEM; - - dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == cl->me_client_id) - break; - - } - - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock; - } - - if (i == dev->me_clients_num) { - rets = -ENODEV; - goto unlock; - } - - cb->response_buffer.size = dev->me_clients[i].props.max_msg_length; - cb->response_buffer.data = - kmalloc(cb->response_buffer.size, GFP_KERNEL); - if (!cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock; - } - dev_dbg(&dev->pdev->dev, "allocation call back data success.\n"); - cb->major_file_operations = MEI_READ; - /* make sure information is zero before we start */ - cb->information = 0; - cb->file_private = (void *) cl; - cl->read_cb = cb; - if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = false; - if (mei_send_flow_control(dev, cl)) { - rets = -ENODEV; - goto unlock; - } - list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list); - } else { - list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list); - } - return rets; -unlock: - mei_free_cb_private(cb); - return rets; -} - -/** - * amthi_write - write iamthif data to amthi client - * - * @dev: the device structure - * @cb: mei call back struct - * - * returns 0 on success, <0 on failure. - */ -int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) -{ - struct mei_msg_hdr mei_hdr; - int ret; - - if (!dev || !cb) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); - - dev->iamthif_state = MEI_IAMTHIF_WRITING; - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_msg_buf_size = cb->request_buffer.size; - memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, - cb->request_buffer.size); - - ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); - if (ret < 0) - return ret; - - if (ret && dev->mei_host_buffer_is_empty) { - ret = 0; - dev->mei_host_buffer_is_empty = false; - if (cb->request_buffer.size > - (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) - -sizeof(struct mei_msg_hdr)) { - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = cb->request_buffer.size; - mei_hdr.msg_complete = 1; - } - - mei_hdr.host_addr = dev->iamthif_cl.host_client_id; - mei_hdr.me_addr = dev->iamthif_cl.me_client_id; - mei_hdr.reserved = 0; - dev->iamthif_msg_buf_index += mei_hdr.length; - if (mei_write_message(dev, &mei_hdr, - (unsigned char *)(dev->iamthif_msg_buf), - mei_hdr.length)) - return -ENODEV; - - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) - return -ENODEV; - dev->iamthif_flow_control_pending = true; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - list_add_tail(&cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } else { - dev_dbg(&dev->pdev->dev, "message does not complete, " - "so add amthi cb to write list.\n"); - list_add_tail(&cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - } else { - if (!(dev->mei_host_buffer_is_empty)) - dev_dbg(&dev->pdev->dev, "host buffer is not empty"); - - dev_dbg(&dev->pdev->dev, "No flow control credentials, " - "so add iamthif cb to write list.\n"); - list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list); - } - return 0; -} - -/** - * iamthif_ioctl_send_msg - send cmd data to amthi client - * - * @dev: the device structure - * - * returns 0 on success, <0 on failure. - */ -void mei_run_next_iamthif_cmd(struct mei_device *dev) -{ - struct mei_cl *cl_tmp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - int status; - - if (!dev) - return; - - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - dev->iamthif_file_object = NULL; - - dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); - - list_for_each_entry_safe(pos, next, - &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) { - list_del(&pos->cb_list); - cl_tmp = (struct mei_cl *)pos->file_private; - - if (cl_tmp && cl_tmp == &dev->iamthif_cl) { - status = amthi_write(dev, pos); - if (status) { - dev_dbg(&dev->pdev->dev, - "amthi write failed status = %d\n", - status); - return; - } - break; - } - } -} - -/** - * mei_free_cb_private - free mei_cb_private related memory - * - * @cb: mei callback struct - */ -void mei_free_cb_private(struct mei_cl_cb *cb) -{ - if (cb == NULL) - return; - - kfree(cb->request_buffer.data); - kfree(cb->response_buffer.data); - kfree(cb); -} diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c deleted file mode 100644 index 7c9321f..0000000 --- a/drivers/staging/mei/main.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/aio.h> -#include <linux/pci.h> -#include <linux/poll.h> -#include <linux/init.h> -#include <linux/ioctl.h> -#include <linux/cdev.h> -#include <linux/sched.h> -#include <linux/uuid.h> -#include <linux/compat.h> -#include <linux/jiffies.h> -#include <linux/interrupt.h> -#include <linux/miscdevice.h> - -#include "mei_dev.h" -#include "mei.h" -#include "interface.h" - - -#define MEI_READ_TIMEOUT 45 -#define MEI_DRIVER_NAME "mei" -#define MEI_DEV_NAME "mei" - -/* - * mei driver strings - */ -static char mei_driver_name[] = MEI_DRIVER_NAME; -static const char mei_driver_string[] = "Intel(R) Management Engine Interface"; - -/* The device pointer */ -/* Currently this driver works as long as there is only a single AMT device. */ -struct pci_dev *mei_device; - -/* mei_pci_tbl - PCI Device ID Table */ -static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, - - /* required last entry */ - {0, } -}; - -MODULE_DEVICE_TABLE(pci, mei_pci_tbl); - -static DEFINE_MUTEX(mei_mutex); - - -/** - * mei_clear_list - removes all callbacks associated with file - * from mei_cb_list - * - * @dev: device structure. - * @file: file structure - * @mei_cb_list: callbacks list - * - * mei_clear_list is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_list(struct mei_device *dev, - struct file *file, struct list_head *mei_cb_list) -{ - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - struct file *file_temp; - bool removed = false; - - /* list all list member */ - list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) { - file_temp = (struct file *)cb_pos->file_object; - /* check if list member associated with a file */ - if (file_temp == file) { - /* remove member from the list */ - list_del(&cb_pos->cb_list); - /* check if cb equal to current iamthif cb */ - if (dev->iamthif_current_cb == cb_pos) { - dev->iamthif_current_cb = NULL; - /* send flow control to iamthif client */ - mei_send_flow_control(dev, &dev->iamthif_cl); - } - /* free all allocated buffers */ - mei_free_cb_private(cb_pos); - cb_pos = NULL; - removed = true; - } - } - return removed; -} - -/** - * mei_clear_lists - removes all callbacks associated with file - * - * @dev: device structure - * @file: file structure - * - * mei_clear_lists is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_lists(struct mei_device *dev, struct file *file) -{ - bool removed = false; - - /* remove callbacks associated with a file */ - mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list); - if (mei_clear_list(dev, file, - &dev->amthi_read_complete_list.mei_cb.cb_list)) - removed = true; - - mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list); - - if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list)) - removed = true; - - /* check if iamthif_current_cb not NULL */ - if (dev->iamthif_current_cb && !removed) { - /* check file and iamthif current cb association */ - if (dev->iamthif_current_cb->file_object == file) { - /* remove cb */ - mei_free_cb_private(dev->iamthif_current_cb); - dev->iamthif_current_cb = NULL; - removed = true; - } - } - return removed; -} -/** - * find_read_list_entry - find read list entry - * - * @dev: device structure - * @file: pointer to file structure - * - * returns cb on success, NULL on error - */ -static struct mei_cl_cb *find_read_list_entry( - struct mei_device *dev, - struct mei_cl *cl) -{ - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); - list_for_each_entry_safe(pos, next, - &dev->read_list.mei_cb.cb_list, cb_list) { - struct mei_cl *cl_temp; - cl_temp = (struct mei_cl *)pos->file_private; - - if (mei_cl_cmp_id(cl, cl_temp)) - return pos; - } - return NULL; -} - -/** - * mei_open - the open function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int mei_open(struct inode *inode, struct file *file) -{ - struct mei_cl *cl; - struct mei_device *dev; - unsigned long cl_id; - int err; - - err = -ENODEV; - if (!mei_device) - goto out; - - dev = pci_get_drvdata(mei_device); - if (!dev) - goto out; - - mutex_lock(&dev->device_lock); - err = -ENOMEM; - cl = mei_cl_allocate(dev); - if (!cl) - goto out_unlock; - - err = -ENODEV; - if (dev->mei_state != MEI_ENABLED) { - dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n", - dev->mei_state); - goto out_unlock; - } - err = -EMFILE; - if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) - goto out_unlock; - - cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); - if (cl_id >= MEI_CLIENTS_MAX) - goto out_unlock; - - cl->host_client_id = cl_id; - - dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id); - - dev->open_handle_count++; - - list_add_tail(&cl->link, &dev->file_list); - - set_bit(cl->host_client_id, dev->host_clients_map); - cl->state = MEI_FILE_INITIALIZING; - cl->sm_state = 0; - - file->private_data = cl; - mutex_unlock(&dev->device_lock); - - return nonseekable_open(inode, file); - -out_unlock: - mutex_unlock(&dev->device_lock); - kfree(cl); -out: - return err; -} - -/** - * mei_release - the release function - * - * @inode: pointer to inode structure - * @file: pointer to file structure - * - * returns 0 on success, <0 on error - */ -static int mei_release(struct inode *inode, struct file *file) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *cb; - struct mei_device *dev; - int rets = 0; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - if (cl != &dev->iamthif_cl) { - if (cl->state == MEI_FILE_CONNECTED) { - cl->state = MEI_FILE_DISCONNECTING; - dev_dbg(&dev->pdev->dev, - "disconnecting client host client = %d, " - "ME client = %d\n", - cl->host_client_id, - cl->me_client_id); - rets = mei_disconnect_host_client(dev, cl); - } - mei_cl_flush_queues(cl); - dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", - cl->host_client_id, - cl->me_client_id); - - if (dev->open_handle_count > 0) { - clear_bit(cl->host_client_id, dev->host_clients_map); - dev->open_handle_count--; - } - mei_remove_client_from_file_list(dev, cl->host_client_id); - - /* free read cb */ - cb = NULL; - if (cl->read_cb) { - cb = find_read_list_entry(dev, cl); - /* Remove entry from read list */ - if (cb) - list_del(&cb->cb_list); - - cb = cl->read_cb; - cl->read_cb = NULL; - } - - file->private_data = NULL; - - if (cb) { - mei_free_cb_private(cb); - cb = NULL; - } - - kfree(cl); - } else { - if (dev->open_handle_count > 0) - dev->open_handle_count--; - - if (dev->iamthif_file_object == file && - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - - dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", - dev->iamthif_state); - dev->iamthif_canceled = true; - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { - dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); - mei_run_next_iamthif_cmd(dev); - } - } - - if (mei_clear_lists(dev, file)) - dev->iamthif_state = MEI_IAMTHIF_IDLE; - - } - mutex_unlock(&dev->device_lock); - return rets; -} - - -/** - * mei_read - the read function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t mei_read(struct file *file, char __user *ubuf, - size_t length, loff_t *offset) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb = NULL; - struct mei_device *dev; - int i; - int rets; - int err; - - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto out; - } - - if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { - /* Do not allow to read watchdog client */ - i = mei_find_me_client_index(dev, mei_wd_guid); - if (i >= 0) { - struct mei_me_client *me_client = &dev->me_clients[i]; - - if (cl->me_client_id == me_client->client_id) { - rets = -EBADF; - goto out; - } - } - } else { - cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - } - - if (cl == &dev->iamthif_cl) { - rets = amthi_read(dev, file, ubuf, length, offset); - goto out; - } - - if (cl->read_cb && cl->read_cb->information > *offset) { - cb = cl->read_cb; - goto copy_buffer; - } else if (cl->read_cb && cl->read_cb->information > 0 && - cl->read_cb->information <= *offset) { - cb = cl->read_cb; - rets = 0; - goto free; - } else if ((!cl->read_cb || !cl->read_cb->information) && - *offset > 0) { - /*Offset needs to be cleaned for contiguous reads*/ - *offset = 0; - rets = 0; - goto out; - } - - err = mei_start_read(dev, cl); - if (err && err != -EBUSY) { - dev_dbg(&dev->pdev->dev, - "mei start read failure with status = %d\n", err); - rets = err; - goto out; - } - - if (MEI_READ_COMPLETE != cl->reading_state && - !waitqueue_active(&cl->rx_wait)) { - if (file->f_flags & O_NONBLOCK) { - rets = -EAGAIN; - goto out; - } - - mutex_unlock(&dev->device_lock); - - if (wait_event_interruptible(cl->rx_wait, - (MEI_READ_COMPLETE == cl->reading_state || - MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state))) { - if (signal_pending(current)) - return -EINTR; - return -ERESTARTSYS; - } - - mutex_lock(&dev->device_lock); - if (MEI_FILE_INITIALIZING == cl->state || - MEI_FILE_DISCONNECTED == cl->state || - MEI_FILE_DISCONNECTING == cl->state) { - rets = -EBUSY; - goto out; - } - } - - cb = cl->read_cb; - - if (!cb) { - rets = -ENODEV; - goto out; - } - if (cl->reading_state != MEI_READ_COMPLETE) { - rets = 0; - goto out; - } - /* now copy the data to user space */ -copy_buffer: - dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", - cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "cb->information - %lu\n", - cb->information); - if (length == 0 || ubuf == NULL || *offset > cb->information) { - rets = -EMSGSIZE; - goto free; - } - - /* length is being truncated to PAGE_SIZE, however, */ - /* information size may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); - - if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { - rets = -EFAULT; - goto free; - } - - rets = length; - *offset += length; - if ((unsigned long)*offset < cb->information) - goto out; - -free: - cb_pos = find_read_list_entry(dev, cl); - /* Remove entry from read list */ - if (cb_pos) - list_del(&cb_pos->cb_list); - mei_free_cb_private(cb); - cl->reading_state = MEI_IDLE; - cl->read_cb = NULL; - cl->read_pending = 0; -out: - dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); - mutex_unlock(&dev->device_lock); - return rets; -} - -/** - * mei_write - the write function. - * - * @file: pointer to file structure - * @ubuf: pointer to user buffer - * @length: buffer length - * @offset: data offset in buffer - * - * returns >=0 data length on success , <0 on error - */ -static ssize_t mei_write(struct file *file, const char __user *ubuf, - size_t length, loff_t *offset) -{ - struct mei_cl *cl = file->private_data; - struct mei_cl_cb *write_cb = NULL; - struct mei_msg_hdr mei_hdr; - struct mei_device *dev; - unsigned long timeout = 0; - int rets; - int i; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) { - mutex_unlock(&dev->device_lock); - return -ENODEV; - } - - if (cl == &dev->iamthif_cl) { - write_cb = find_amthi_read_list_entry(dev, file); - - if (write_cb) { - timeout = write_cb->read_time + - msecs_to_jiffies(IAMTHIF_READ_TIMER); - - if (time_after(jiffies, timeout) || - cl->reading_state == MEI_READ_COMPLETE) { - *offset = 0; - list_del(&write_cb->cb_list); - mei_free_cb_private(write_cb); - write_cb = NULL; - } - } - } - - /* free entry used in read */ - if (cl->reading_state == MEI_READ_COMPLETE) { - *offset = 0; - write_cb = find_read_list_entry(dev, cl); - if (write_cb) { - list_del(&write_cb->cb_list); - mei_free_cb_private(write_cb); - write_cb = NULL; - cl->reading_state = MEI_IDLE; - cl->read_cb = NULL; - cl->read_pending = 0; - } - } else if (cl->reading_state == MEI_IDLE && !cl->read_pending) - *offset = 0; - - - write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!write_cb) { - mutex_unlock(&dev->device_lock); - return -ENOMEM; - } - - write_cb->file_object = file; - write_cb->file_private = cl; - write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); - rets = -ENOMEM; - if (!write_cb->request_buffer.data) - goto unlock_dev; - - dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length); - - rets = -EFAULT; - if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) - goto unlock_dev; - - cl->sm_state = 0; - if (length == 4 && - ((memcmp(mei_wd_state_independence_msg[0], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[1], - write_cb->request_buffer.data, 4) == 0) || - (memcmp(mei_wd_state_independence_msg[2], - write_cb->request_buffer.data, 4) == 0))) - cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - - INIT_LIST_HEAD(&write_cb->cb_list); - if (cl == &dev->iamthif_cl) { - write_cb->response_buffer.data = - kmalloc(dev->iamthif_mtu, GFP_KERNEL); - if (!write_cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock_dev; - } - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto unlock_dev; - } - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - dev->iamthif_cl.me_client_id) - break; - } - - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } - if (i == dev->me_clients_num || - (dev->me_clients[i].client_id != - dev->iamthif_cl.me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } else if (length > dev->me_clients[i].props.max_msg_length || - length <= 0) { - rets = -EMSGSIZE; - goto unlock_dev; - } - - write_cb->response_buffer.size = dev->iamthif_mtu; - write_cb->major_file_operations = MEI_IOCTL; - write_cb->information = 0; - write_cb->request_buffer.size = length; - if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - goto unlock_dev; - } - - if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, "amthi_state = %d\n", - (int) dev->iamthif_state); - dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); - list_add_tail(&write_cb->cb_list, - &dev->amthi_cmd_list.mei_cb.cb_list); - rets = length; - } else { - dev_dbg(&dev->pdev->dev, "call amthi write\n"); - rets = amthi_write(dev, write_cb); - - if (rets) { - dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n", - rets); - goto unlock_dev; - } - rets = length; - } - mutex_unlock(&dev->device_lock); - return rets; - } - - write_cb->major_file_operations = MEI_WRITE; - /* make sure information is zero before we start */ - - write_cb->information = 0; - write_cb->request_buffer.size = length; - - dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - if (cl->state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", - cl->host_client_id, - cl->me_client_id); - goto unlock_dev; - } - for (i = 0; i < dev->me_clients_num; i++) { - if (dev->me_clients[i].client_id == - cl->me_client_id) - break; - } - if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) { - rets = -ENODEV; - goto unlock_dev; - } - if (i == dev->me_clients_num) { - rets = -ENODEV; - goto unlock_dev; - } - if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { - rets = -EINVAL; - goto unlock_dev; - } - write_cb->file_private = cl; - - rets = mei_flow_ctrl_creds(dev, cl); - if (rets < 0) - goto unlock_dev; - - if (rets && dev->mei_host_buffer_is_empty) { - rets = 0; - dev->mei_host_buffer_is_empty = false; - if (length > ((((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - sizeof(struct mei_msg_hdr))) { - - mei_hdr.length = - (((dev->host_hw_state & H_CBD) >> 24) * - sizeof(u32)) - - sizeof(struct mei_msg_hdr); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = length; - mei_hdr.msg_complete = 1; - } - mei_hdr.host_addr = cl->host_client_id; - mei_hdr.me_addr = cl->me_client_id; - mei_hdr.reserved = 0; - dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", - *((u32 *) &mei_hdr)); - if (mei_write_message(dev, &mei_hdr, - (unsigned char *) (write_cb->request_buffer.data), - mei_hdr.length)) { - rets = -ENODEV; - goto unlock_dev; - } - cl->writing_state = MEI_WRITING; - write_cb->information = mei_hdr.length; - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, cl)) { - rets = -ENODEV; - goto unlock_dev; - } - list_add_tail(&write_cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); - } else { - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - - } else { - - write_cb->information = 0; - cl->writing_state = MEI_WRITING; - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); - } - mutex_unlock(&dev->device_lock); - return length; - -unlock_dev: - mutex_unlock(&dev->device_lock); - mei_free_cb_private(write_cb); - return rets; -} - - -/** - * mei_ioctl - the IOCTL function - * - * @file: pointer to file structure - * @cmd: ioctl command - * @data: pointer to mei message structure - * - * returns 0 on success , <0 on error - */ -static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) -{ - struct mei_device *dev; - struct mei_cl *cl = file->private_data; - struct mei_connect_client_data *connect_data = NULL; - int rets; - - if (cmd != IOCTL_MEI_CONNECT_CLIENT) - return -EINVAL; - - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - - dev = cl->dev; - - dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); - - mutex_lock(&dev->device_lock); - if (dev->mei_state != MEI_ENABLED) { - rets = -ENODEV; - goto out; - } - - dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); - - connect_data = kzalloc(sizeof(struct mei_connect_client_data), - GFP_KERNEL); - if (!connect_data) { - rets = -ENOMEM; - goto out; - } - dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); - if (copy_from_user(connect_data, (char __user *)data, - sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); - rets = -EFAULT; - goto out; - } - rets = mei_ioctl_connect_client(file, connect_data); - - /* if all is ok, copying the data back to user. */ - if (rets) - goto out; - - dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); - if (copy_to_user((char __user *)data, connect_data, - sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); - rets = -EFAULT; - goto out; - } - -out: - kfree(connect_data); - mutex_unlock(&dev->device_lock); - return rets; -} - -/** - * mei_compat_ioctl - the compat IOCTL function - * - * @file: pointer to file structure - * @cmd: ioctl command - * @data: pointer to mei message structure - * - * returns 0 on success , <0 on error - */ -#ifdef CONFIG_COMPAT -static long mei_compat_ioctl(struct file *file, - unsigned int cmd, unsigned long data) -{ - return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data)); -} -#endif - - -/** - * mei_poll - the poll function - * - * @file: pointer to file structure - * @wait: pointer to poll_table structure - * - * returns poll mask - */ -static unsigned int mei_poll(struct file *file, poll_table *wait) -{ - struct mei_cl *cl = file->private_data; - struct mei_device *dev; - unsigned int mask = 0; - - if (WARN_ON(!cl || !cl->dev)) - return mask; - - dev = cl->dev; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) - goto out; - - - if (cl == &dev->iamthif_cl) { - mutex_unlock(&dev->device_lock); - poll_wait(file, &dev->iamthif_cl.wait, wait); - mutex_lock(&dev->device_lock); - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && - dev->iamthif_file_object == file) { - mask |= (POLLIN | POLLRDNORM); - dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); - mei_run_next_iamthif_cmd(dev); - } - goto out; - } - - mutex_unlock(&dev->device_lock); - poll_wait(file, &cl->tx_wait, wait); - mutex_lock(&dev->device_lock); - if (MEI_WRITE_COMPLETE == cl->writing_state) - mask |= (POLLIN | POLLRDNORM); - -out: - mutex_unlock(&dev->device_lock); - return mask; -} - -/* - * file operations structure will be used for mei char device. - */ -static const struct file_operations mei_fops = { - .owner = THIS_MODULE, - .read = mei_read, - .unlocked_ioctl = mei_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = mei_compat_ioctl, -#endif - .open = mei_open, - .release = mei_release, - .write = mei_write, - .poll = mei_poll, - .llseek = no_llseek -}; - - -/* - * Misc Device Struct - */ -static struct miscdevice mei_misc_device = { - .name = MEI_DRIVER_NAME, - .fops = &mei_fops, - .minor = MISC_DYNAMIC_MINOR, -}; - -/** - * mei_probe - Device Initialization Routine - * - * @pdev: PCI device structure - * @ent: entry in kcs_pci_tbl - * - * returns 0 on success, <0 on failure. - */ -static int __devinit mei_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct mei_device *dev; - int err; - - mutex_lock(&mei_mutex); - if (mei_device) { - err = -EEXIST; - goto end; - } - /* enable pci dev */ - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "mei: Failed to enable pci device.\n"); - goto end; - } - /* set PCI host mastering */ - pci_set_master(pdev); - /* pci request regions for mei driver */ - err = pci_request_regions(pdev, mei_driver_name); - if (err) { - printk(KERN_ERR "mei: Failed to get pci regions.\n"); - goto disable_device; - } - /* allocates and initializes the mei dev structure */ - dev = mei_device_init(pdev); - if (!dev) { - err = -ENOMEM; - goto release_regions; - } - /* mapping IO device memory */ - dev->mem_addr = pci_iomap(pdev, 0, 0); - if (!dev->mem_addr) { - printk(KERN_ERR "mei: mapping I/O device memory failure.\n"); - err = -ENOMEM; - goto free_device; - } - pci_enable_msi(pdev); - - /* request and enable interrupt */ - if (pci_dev_msi_enabled(pdev)) - err = request_threaded_irq(pdev->irq, - NULL, - mei_interrupt_thread_handler, - 0, mei_driver_name, dev); - else - err = request_threaded_irq(pdev->irq, - mei_interrupt_quick_handler, - mei_interrupt_thread_handler, - IRQF_SHARED, mei_driver_name, dev); - - if (err) { - printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", - pdev->irq); - goto unmap_memory; - } - INIT_DELAYED_WORK(&dev->timer_work, mei_timer); - if (mei_hw_init(dev)) { - printk(KERN_ERR "mei: Init hw failure.\n"); - err = -ENODEV; - goto release_irq; - } - - err = misc_register(&mei_misc_device); - if (err) - goto release_irq; - - mei_device = pdev; - pci_set_drvdata(pdev, dev); - - - schedule_delayed_work(&dev->timer_work, HZ); - - mutex_unlock(&mei_mutex); - - pr_debug("mei: Driver initialization successful.\n"); - - return 0; - -release_irq: - /* disable interrupts */ - dev->host_hw_state = mei_hcsr_read(dev); - mei_disable_interrupts(dev); - flush_scheduled_work(); - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); -unmap_memory: - pci_iounmap(pdev, dev->mem_addr); -free_device: - kfree(dev); -release_regions: - pci_release_regions(pdev); -disable_device: - pci_disable_device(pdev); -end: - mutex_unlock(&mei_mutex); - printk(KERN_ERR "mei: Driver initialization failed.\n"); - return err; -} - -/** - * mei_remove - Device Removal Routine - * - * @pdev: PCI device structure - * - * mei_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. - */ -static void __devexit mei_remove(struct pci_dev *pdev) -{ - struct mei_device *dev; - - if (mei_device != pdev) - return; - - dev = pci_get_drvdata(pdev); - if (!dev) - return; - - mutex_lock(&dev->device_lock); - - mei_wd_stop(dev, false); - - mei_device = NULL; - - if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { - dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->iamthif_cl); - } - if (dev->wd_cl.state == MEI_FILE_CONNECTED) { - dev->wd_cl.state = MEI_FILE_DISCONNECTING; - mei_disconnect_host_client(dev, &dev->wd_cl); - } - - /* Unregistering watchdog device */ - mei_watchdog_unregister(dev); - - /* remove entry if already in list */ - dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id); - mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); - - dev->iamthif_current_cb = NULL; - dev->me_clients_num = 0; - - mutex_unlock(&dev->device_lock); - - flush_scheduled_work(); - - /* disable interrupts */ - mei_disable_interrupts(dev); - - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); - pci_set_drvdata(pdev, NULL); - - if (dev->mem_addr) - pci_iounmap(pdev, dev->mem_addr); - - kfree(dev); - - pci_release_regions(pdev); - pci_disable_device(pdev); -} -#ifdef CONFIG_PM -static int mei_pci_suspend(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct mei_device *dev = pci_get_drvdata(pdev); - int err; - - if (!dev) - return -ENODEV; - mutex_lock(&dev->device_lock); - /* Stop watchdog if exists */ - err = mei_wd_stop(dev, true); - /* Set new mei state */ - if (dev->mei_state == MEI_ENABLED || - dev->mei_state == MEI_RECOVERING_FROM_RESET) { - dev->mei_state = MEI_POWER_DOWN; - mei_reset(dev, 0); - } - mutex_unlock(&dev->device_lock); - - free_irq(pdev->irq, dev); - pci_disable_msi(pdev); - - return err; -} - -static int mei_pci_resume(struct device *device) -{ - struct pci_dev *pdev = to_pci_dev(device); - struct mei_device *dev; - int err; - - dev = pci_get_drvdata(pdev); - if (!dev) - return -ENODEV; - - pci_enable_msi(pdev); - - /* request and enable interrupt */ - if (pci_dev_msi_enabled(pdev)) - err = request_threaded_irq(pdev->irq, - NULL, - mei_interrupt_thread_handler, - 0, mei_driver_name, dev); - else - err = request_threaded_irq(pdev->irq, - mei_interrupt_quick_handler, - mei_interrupt_thread_handler, - IRQF_SHARED, mei_driver_name, dev); - - if (err) { - printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", - pdev->irq); - return err; - } - - mutex_lock(&dev->device_lock); - dev->mei_state = MEI_POWER_UP; - mei_reset(dev, 1); - mutex_unlock(&dev->device_lock); - - /* Start timer if stopped in suspend */ - schedule_delayed_work(&dev->timer_work, HZ); - - return err; -} -static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); -#define MEI_PM_OPS (&mei_pm_ops) -#else -#define MEI_PM_OPS NULL -#endif /* CONFIG_PM */ -/* - * PCI driver structure - */ -static struct pci_driver mei_driver = { - .name = mei_driver_name, - .id_table = mei_pci_tbl, - .probe = mei_probe, - .remove = __devexit_p(mei_remove), - .shutdown = __devexit_p(mei_remove), - .driver.pm = MEI_PM_OPS, -}; - -/** - * mei_init_module - Driver Registration Routine - * - * mei_init_module is the first routine called when the driver is - * loaded. All it does is to register with the PCI subsystem. - * - * returns 0 on success, <0 on failure. - */ -static int __init mei_init_module(void) -{ - int ret; - - pr_debug("mei: %s\n", mei_driver_string); - /* init pci module */ - ret = pci_register_driver(&mei_driver); - if (ret < 0) - printk(KERN_ERR "mei: Error registering driver.\n"); - - return ret; -} - -module_init(mei_init_module); - -/** - * mei_exit_module - Driver Exit Cleanup Routine - * - * mei_exit_module is called just before the driver is removed - * from memory. - */ -static void __exit mei_exit_module(void) -{ - misc_deregister(&mei_misc_device); - pci_unregister_driver(&mei_driver); - - pr_debug("mei: Driver unloaded successfully.\n"); -} - -module_exit(mei_exit_module); - - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/mei/mei-amt-version.c b/drivers/staging/mei/mei-amt-version.c deleted file mode 100644 index ac2a507..0000000 --- a/drivers/staging/mei/mei-amt-version.c +++ /dev/null @@ -1,481 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <errno.h> -#include <stdint.h> -#include <stdbool.h> -#include <bits/wordsize.h> -#include "mei.h" - -/***************************************************************************** - * Intel Management Engine Interface - *****************************************************************************/ - -#define mei_msg(_me, fmt, ARGS...) do { \ - if (_me->verbose) \ - fprintf(stderr, fmt, ##ARGS); \ -} while (0) - -#define mei_err(_me, fmt, ARGS...) do { \ - fprintf(stderr, "Error: " fmt, ##ARGS); \ -} while (0) - -struct mei { - uuid_le guid; - bool initialized; - bool verbose; - unsigned int buf_size; - unsigned char prot_ver; - int fd; -}; - -static void mei_deinit(struct mei *cl) -{ - if (cl->fd != -1) - close(cl->fd); - cl->fd = -1; - cl->buf_size = 0; - cl->prot_ver = 0; - cl->initialized = false; -} - -static bool mei_init(struct mei *me, const uuid_le *guid, - unsigned char req_protocol_version, bool verbose) -{ - int result; - struct mei_client *cl; - struct mei_connect_client_data data; - - mei_deinit(me); - - me->verbose = verbose; - - me->fd = open("/dev/mei", O_RDWR); - if (me->fd == -1) { - mei_err(me, "Cannot establish a handle to the Intel MEI driver\n"); - goto err; - } - memcpy(&me->guid, guid, sizeof(*guid)); - memset(&data, 0, sizeof(data)); - me->initialized = true; - - memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid)); - result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data); - if (result) { - mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result); - goto err; - } - cl = &data.out_client_properties; - mei_msg(me, "max_message_length %d\n", cl->max_msg_length); - mei_msg(me, "protocol_version %d\n", cl->protocol_version); - - if ((req_protocol_version > 0) && - (cl->protocol_version != req_protocol_version)) { - mei_err(me, "Intel MEI protocol version not supported\n"); - goto err; - } - - me->buf_size = cl->max_msg_length; - me->prot_ver = cl->protocol_version; - - return true; -err: - mei_deinit(me); - return false; -} - -static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - ssize_t rc; - - mei_msg(me, "call read length = %zd\n", len); - - rc = read(me->fd, buffer, len); - if (rc < 0) { - mei_err(me, "read failed with status %zd %s\n", - rc, strerror(errno)); - mei_deinit(me); - } else { - mei_msg(me, "read succeeded with result %zd\n", rc); - } - return rc; -} - -static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer, - ssize_t len, unsigned long timeout) -{ - struct timeval tv; - ssize_t written; - ssize_t rc; - fd_set set; - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000000; - - mei_msg(me, "call write length = %zd\n", len); - - written = write(me->fd, buffer, len); - if (written < 0) { - rc = -errno; - mei_err(me, "write failed with status %zd %s\n", - written, strerror(errno)); - goto out; - } - - FD_ZERO(&set); - FD_SET(me->fd, &set); - rc = select(me->fd + 1 , &set, NULL, NULL, &tv); - if (rc > 0 && FD_ISSET(me->fd, &set)) { - mei_msg(me, "write success\n"); - } else if (rc == 0) { - mei_err(me, "write failed on timeout with status\n"); - goto out; - } else { /* rc < 0 */ - mei_err(me, "write failed on select with status %zd\n", rc); - goto out; - } - - rc = written; -out: - if (rc < 0) - mei_deinit(me); - - return rc; -} - -/*************************************************************************** - * Intel Advanced Management Technolgy ME Client - ***************************************************************************/ - -#define AMT_MAJOR_VERSION 1 -#define AMT_MINOR_VERSION 1 - -#define AMT_STATUS_SUCCESS 0x0 -#define AMT_STATUS_INTERNAL_ERROR 0x1 -#define AMT_STATUS_NOT_READY 0x2 -#define AMT_STATUS_INVALID_AMT_MODE 0x3 -#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 - -#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 -#define AMT_STATUS_SDK_RESOURCES 0x1004 - - -#define AMT_BIOS_VERSION_LEN 65 -#define AMT_VERSIONS_NUMBER 50 -#define AMT_UNICODE_STRING_LEN 20 - -struct amt_unicode_string { - uint16_t length; - char string[AMT_UNICODE_STRING_LEN]; -} __attribute__((packed)); - -struct amt_version_type { - struct amt_unicode_string description; - struct amt_unicode_string version; -} __attribute__((packed)); - -struct amt_version { - uint8_t major; - uint8_t minor; -} __attribute__((packed)); - -struct amt_code_versions { - uint8_t bios[AMT_BIOS_VERSION_LEN]; - uint32_t count; - struct amt_version_type versions[AMT_VERSIONS_NUMBER]; -} __attribute__((packed)); - -/*************************************************************************** - * Intel Advanced Management Technolgy Host Interface - ***************************************************************************/ - -struct amt_host_if_msg_header { - struct amt_version version; - uint16_t _reserved; - uint32_t command; - uint32_t length; -} __attribute__((packed)); - -struct amt_host_if_resp_header { - struct amt_host_if_msg_header header; - uint32_t status; - unsigned char data[0]; -} __attribute__((packed)); - -const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ - 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); - -#define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A -#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A - -const struct amt_host_if_msg_header CODE_VERSION_REQ = { - .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, - ._reserved = 0, - .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, - .length = 0 -}; - - -struct amt_host_if { - struct mei mei_cl; - unsigned long send_timeout; - bool initialized; -}; - - -static bool amt_host_if_init(struct amt_host_if *acmd, - unsigned long send_timeout, bool verbose) -{ - acmd->send_timeout = (send_timeout) ? send_timeout : 20000; - acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose); - return acmd->initialized; -} - -static void amt_host_if_deinit(struct amt_host_if *acmd) -{ - mei_deinit(&acmd->mei_cl); - acmd->initialized = false; -} - -static uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp) -{ - uint32_t status = AMT_STATUS_SUCCESS; - struct amt_code_versions *code_ver; - size_t code_ver_len; - uint32_t ver_type_cnt; - uint32_t len; - uint32_t i; - - code_ver = (struct amt_code_versions *)resp->data; - /* length - sizeof(status) */ - code_ver_len = resp->header.length - sizeof(uint32_t); - ver_type_cnt = code_ver_len - - sizeof(code_ver->bios) - - sizeof(code_ver->count); - if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - for (i = 0; i < code_ver->count; i++) { - len = code_ver->versions[i].description.length; - - if (len > AMT_UNICODE_STRING_LEN) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - - len = code_ver->versions[i].version.length; - if (code_ver->versions[i].version.string[len] != '\0' || - len != strlen(code_ver->versions[i].version.string)) { - status = AMT_STATUS_INTERNAL_ERROR; - goto out; - } - } -out: - return status; -} - -static uint32_t amt_verify_response_header(uint32_t command, - const struct amt_host_if_msg_header *resp_hdr, - uint32_t response_size) -{ - if (response_size < sizeof(struct amt_host_if_resp_header)) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (response_size != (resp_hdr->length + - sizeof(struct amt_host_if_msg_header))) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->command != command) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->_reserved != 0) { - return AMT_STATUS_INTERNAL_ERROR; - } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || - resp_hdr->version.minor < AMT_MINOR_VERSION) { - return AMT_STATUS_INTERNAL_ERROR; - } - return AMT_STATUS_SUCCESS; -} - -static uint32_t amt_host_if_call(struct amt_host_if *acmd, - const unsigned char *command, ssize_t command_sz, - uint8_t **read_buf, uint32_t rcmd, - unsigned int expected_sz) -{ - uint32_t in_buf_sz; - uint32_t out_buf_sz; - ssize_t written; - uint32_t status; - struct amt_host_if_resp_header *msg_hdr; - - in_buf_sz = acmd->mei_cl.buf_size; - *read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz); - if (*read_buf == NULL) - return AMT_STATUS_SDK_RESOURCES; - memset(*read_buf, 0, in_buf_sz); - msg_hdr = (struct amt_host_if_resp_header *)*read_buf; - - written = mei_send_msg(&acmd->mei_cl, - command, command_sz, acmd->send_timeout); - if (written != command_sz) - return AMT_STATUS_INTERNAL_ERROR; - - out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000); - if (out_buf_sz <= 0) - return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; - - status = msg_hdr->status; - if (status != AMT_STATUS_SUCCESS) - return status; - - status = amt_verify_response_header(rcmd, - &msg_hdr->header, out_buf_sz); - if (status != AMT_STATUS_SUCCESS) - return status; - - if (expected_sz && expected_sz != out_buf_sz) - return AMT_STATUS_INTERNAL_ERROR; - - return AMT_STATUS_SUCCESS; -} - - -static uint32_t amt_get_code_versions(struct amt_host_if *cmd, - struct amt_code_versions *versions) -{ - struct amt_host_if_resp_header *response = NULL; - uint32_t status; - - status = amt_host_if_call(cmd, - (const unsigned char *)&CODE_VERSION_REQ, - sizeof(CODE_VERSION_REQ), - (uint8_t **)&response, - AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0); - - if (status != AMT_STATUS_SUCCESS) - goto out; - - status = amt_verify_code_versions(response); - if (status != AMT_STATUS_SUCCESS) - goto out; - - memcpy(versions, response->data, sizeof(struct amt_code_versions)); -out: - if (response != NULL) - free(response); - - return status; -} - -/************************** end of amt_host_if_command ***********************/ -int main(int argc, char **argv) -{ - struct amt_code_versions ver; - struct amt_host_if acmd; - unsigned int i; - uint32_t status; - int ret; - bool verbose; - - verbose = (argc > 1 && strcmp(argv[1], "-v") == 0); - - if (!amt_host_if_init(&acmd, 5000, verbose)) { - ret = 1; - goto out; - } - - status = amt_get_code_versions(&acmd, &ver); - - amt_host_if_deinit(&acmd); - - switch (status) { - case AMT_STATUS_HOST_IF_EMPTY_RESPONSE: - printf("Intel AMT: DISABLED\n"); - ret = 0; - break; - case AMT_STATUS_SUCCESS: - printf("Intel AMT: ENABLED\n"); - for (i = 0; i < ver.count; i++) { - printf("%s:\t%s\n", ver.versions[i].description.string, - ver.versions[i].version.string); - } - ret = 0; - break; - default: - printf("An error has occurred\n"); - ret = 1; - break; - } - -out: - return ret; -} diff --git a/drivers/staging/mei/mei.h b/drivers/staging/mei/mei.h deleted file mode 100644 index bc0d8b6..0000000 --- a/drivers/staging/mei/mei.h +++ /dev/null @@ -1,110 +0,0 @@ -/****************************************************************************** - * Intel Management Engine Interface (Intel MEI) Linux driver - * Intel MEI Interface Header - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Corporation. - * linux-mei@linux.intel.com - * http://www.intel.com - * - * BSD LICENSE - * - * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#ifndef _LINUX_MEI_H -#define _LINUX_MEI_H - -#include <linux/uuid.h> - -/* - * This IOCTL is used to associate the current file descriptor with a - * FW Client (given by UUID). This opens a communication channel - * between a host client and a FW client. From this point every read and write - * will communicate with the associated FW client. - * Only in close() (file_operation release()) the communication between - * the clients is disconnected - * - * The IOCTL argument is a struct with a union that contains - * the input parameter and the output parameter for this IOCTL. - * - * The input parameter is UUID of the FW Client. - * The output parameter is the properties of the FW client - * (FW protocol version and max message size). - * - */ -#define IOCTL_MEI_CONNECT_CLIENT \ - _IOWR('H' , 0x01, struct mei_connect_client_data) - -/* - * Intel MEI client information struct - */ -struct mei_client { - __u32 max_msg_length; - __u8 protocol_version; - __u8 reserved[3]; -}; - -/* - * IOCTL Connect Client Data structure - */ -struct mei_connect_client_data { - union { - uuid_le in_client_uuid; - struct mei_client out_client_properties; - }; -}; - -#endif /* _LINUX_MEI_H */ diff --git a/drivers/staging/mei/mei.txt b/drivers/staging/mei/mei.txt deleted file mode 100644 index 2785697..0000000 --- a/drivers/staging/mei/mei.txt +++ /dev/null @@ -1,215 +0,0 @@ -Intel(R) Management Engine Interface (Intel(R) MEI) -======================= - -Introduction -======================= - -The Intel Management Engine (Intel ME) is an isolated and protected computing -resource (Co-processor) residing inside certain Intel chipsets. The Intel ME -provides support for computer/IT management features. The feature set -depends on the Intel chipset SKU. - -The Intel Management Engine Interface (Intel MEI, previously known as HECI) -is the interface between the Host and Intel ME. This interface is exposed -to the host as a PCI device. The Intel MEI Driver is in charge of the -communication channel between a host application and the Intel ME feature. - -Each Intel ME feature (Intel ME Client) is addressed by a GUID/UUID and -each client has its own protocol. The protocol is message-based with a -header and payload up to 512 bytes. - -Prominent usage of the Intel ME Interface is to communicate with Intel(R) -Active Management Technology (Intel AMT)implemented in firmware running on -the Intel ME. - -Intel AMT provides the ability to manage a host remotely out-of-band (OOB) -even when the operating system running on the host processor has crashed or -is in a sleep state. - -Some examples of Intel AMT usage are: - - Monitoring hardware state and platform components - - Remote power off/on (useful for green computing or overnight IT - maintenance) - - OS updates - - Storage of useful platform information such as software assets - - Built-in hardware KVM - - Selective network isolation of Ethernet and IP protocol flows based - on policies set by a remote management console - - IDE device redirection from remote management console - -Intel AMT (OOB) communication is based on SOAP (deprecated -starting with Release 6.0) over HTTP/S or WS-Management protocol over -HTTP/S that are received from a remote management console application. - -For more information about Intel AMT: -http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - -Intel MEI Driver -======================= - -The driver exposes a misc device called /dev/mei. - -An application maintains communication with an Intel ME feature while -/dev/mei is open. The binding to a specific features is performed by calling -MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID. -The number of instances of an Intel ME feature that can be opened -at the same time depends on the Intel ME feature, but most of the -features allow only a single instance. - -The Intel AMT Host Interface (Intel AMTHI) feature supports multiple -simultaneous user applications. Therefore, the Intel MEI driver handles -this internally by maintaining request queues for the applications. - -The driver is oblivious to data that is passed between firmware feature -and host application. - -Because some of the Intel ME features can change the system -configuration, the driver by default allows only a privileged -user to access it. - -A code snippet for an application communicating with -Intel AMTHI client: - struct mei_connect_client_data data; - fd = open(MEI_DEVICE); - - data.d.in_client_uuid = AMTHI_UUID; - - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data); - - printf("Ver=%d, MaxLen=%ld\n", - data.d.in_client_uuid.protocol_version, - data.d.in_client_uuid.max_msg_length); - - [...] - - write(fd, amthi_req_data, amthi_req_data_len); - - [...] - - read(fd, &amthi_res_data, amthi_res_data_len); - - [...] - close(fd); - -IOCTL: -====== -The Intel MEI Driver supports the following IOCTL command: - IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). - - usage: - struct mei_connect_client_data clientData; - ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &clientData); - - inputs: - mei_connect_client_data struct contain the following - input field: - - in_client_uuid - UUID of the FW Feature that needs - to connect to. - outputs: - out_client_properties - Client Properties: MTU and Protocol Version. - - error returns: - EINVAL Wrong IOCTL Number - ENODEV Device or Connection is not initialized or ready. - (e.g. Wrong UUID) - ENOMEM Unable to allocate memory to client internal data. - EFAULT Fatal Error (e.g. Unable to access user input data) - EBUSY Connection Already Open - - Notes: - max_msg_length (MTU) in client properties describes the maximum - data that can be sent or received. (e.g. if MTU=2K, can send - requests up to bytes 2k and received responses upto 2k bytes). - -Intel ME Applications: -============== - -1) Intel Local Management Service (Intel LMS) - - Applications running locally on the platform communicate with Intel AMT Release - 2.0 and later releases in the same way that network applications do via SOAP - over HTTP (deprecated starting with Release 6.0) or with WS-Management over - SOAP over HTTP. This means that some Intel AMT features can be accessed from a - local application using the same network interface as a remote application - communicating with Intel AMT over the network. - - When a local application sends a message addressed to the local Intel AMT host - name, the Intel LMS, which listens for traffic directed to the host name, - intercepts the message and routes it to the Intel MEI. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "About Intel AMT" => "Local Access" - - For downloading Intel LMS: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - The Intel LMS opens a connection using the Intel MEI driver to the Intel LMS - firmware feature using a defined UUID and then communicates with the feature - using a protocol called Intel AMT Port Forwarding Protocol(Intel APF protocol). - The protocol is used to maintain multiple sessions with Intel AMT from a - single application. - - See the protocol specification in the Intel AMT Software Development Kit(SDK) - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "SDK Resources" => "Intel(R) vPro(TM) Gateway(MPS)" - => "Information for Intel(R) vPro(TM) Gateway Developers" - => "Description of the Intel AMT Port Forwarding (APF)Protocol" - - 2) Intel AMT Remote configuration using a Local Agent - A Local Agent enables IT personnel to configure Intel AMT out-of-the-box - without requiring installing additional data to enable setup. The remote - configuration process may involve an ISV-developed remote configuration - agent that runs on the host. - For more information: - http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide - Under "Setup and Configuration of Intel AMT" => - "SDK Tools Supporting Setup and Configuration" => - "Using the Local Agent Sample" - - An open source Intel AMT configuration utility, implementing a local agent - that accesses the Intel MEI driver, can be found here: - http://software.intel.com/en-us/articles/download-the-latest-intel-amt-open-source-drivers/ - - -Intel AMT OS Health Watchdog: -============================= -The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog. -Whenever the OS hangs or crashes, Intel AMT will send an event -to any subscriber to this event. This mechanism means that -IT knows when a platform crashes even when there is a hard failure on the host. - -The Intel AMT Watchdog is composed of two parts: - 1) Firmware feature - receives the heartbeats - and sends an event when the heartbeats stop. - 2) Intel MEI driver - connects to the watchdog feature, configures the - watchdog and sends the heartbeats. - -The Intel MEI driver uses the kernel watchdog to configure the Intel AMT -Watchdog and to send heartbeats to it. The default timeout of the -watchdog is 120 seconds. - -If the Intel AMT Watchdog feature does not exist (i.e. the connection failed), -the Intel MEI driver will disable the sending of heartbeats. - -Supported Chipsets: -================== -7 Series Chipset Family -6 Series Chipset Family -5 Series Chipset Family -4 Series Chipset Family -Mobile 4 Series Chipset Family -ICH9 -82946GZ/GL -82G35 Express -82Q963/Q965 -82P965/G965 -Mobile PM965/GM965 -Mobile GME965/GLE960 -82Q35 Express -82G33/G31/P35/P31 Express -82Q33 Express -82X38/X48 Express - ---- -linux-mei@linux.intel.com diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h deleted file mode 100644 index 10b1b4e..0000000 --- a/drivers/staging/mei/mei_dev.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ - -#ifndef _MEI_DEV_H_ -#define _MEI_DEV_H_ - -#include <linux/types.h> -#include <linux/watchdog.h> -#include "mei.h" -#include "hw.h" - -/* - * watch dog definition - */ -#define MEI_WATCHDOG_DATA_SIZE 16 -#define MEI_START_WD_DATA_SIZE 20 -#define MEI_WD_PARAMS_SIZE 4 -#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) - -#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32)) - -/* - * MEI PCI Device object - */ -extern struct pci_dev *mei_device; - - -/* - * AMTHI Client UUID - */ -extern const uuid_le mei_amthi_guid; - -/* - * Watchdog Client UUID - */ -extern const uuid_le mei_wd_guid; - -/* - * Watchdog independence state message - */ -extern const u8 mei_wd_state_independence_msg[3][4]; - -/* - * Number of File descriptors/handles - * that can be opened to the driver. - * - * Limit to 253: 255 Total Clients - * minus internal client for AMTHI - * minus internal client for Watchdog - */ -#define MEI_MAX_OPEN_HANDLE_COUNT 253 - -/* - * Number of Maximum MEI Clients - */ -#define MEI_CLIENTS_MAX 255 - -/* File state */ -enum file_state { - MEI_FILE_INITIALIZING = 0, - MEI_FILE_CONNECTING, - MEI_FILE_CONNECTED, - MEI_FILE_DISCONNECTING, - MEI_FILE_DISCONNECTED -}; - -/* MEI device states */ -enum mei_states { - MEI_INITIALIZING = 0, - MEI_INIT_CLIENTS, - MEI_ENABLED, - MEI_RESETING, - MEI_DISABLED, - MEI_RECOVERING_FROM_RESET, - MEI_POWER_DOWN, - MEI_POWER_UP -}; - -/* init clients states*/ -enum mei_init_clients_states { - MEI_START_MESSAGE = 0, - MEI_ENUM_CLIENTS_MESSAGE, - MEI_CLIENT_PROPERTIES_MESSAGE -}; - -enum iamthif_states { - MEI_IAMTHIF_IDLE, - MEI_IAMTHIF_WRITING, - MEI_IAMTHIF_FLOW_CONTROL, - MEI_IAMTHIF_READING, - MEI_IAMTHIF_READ_COMPLETE -}; - -enum mei_file_transaction_states { - MEI_IDLE, - MEI_WRITING, - MEI_WRITE_COMPLETE, - MEI_FLOW_CONTROL, - MEI_READING, - MEI_READ_COMPLETE -}; - -/* MEI CB */ -enum mei_cb_major_types { - MEI_READ = 0, - MEI_WRITE, - MEI_IOCTL, - MEI_OPEN, - MEI_CLOSE -}; - -/* - * Intel MEI message data struct - */ -struct mei_message_data { - u32 size; - unsigned char *data; -} __packed; - - -struct mei_cl_cb { - struct list_head cb_list; - enum mei_cb_major_types major_file_operations; - void *file_private; - struct mei_message_data request_buffer; - struct mei_message_data response_buffer; - unsigned long information; - unsigned long read_time; - struct file *file_object; -}; - -/* MEI client instance carried as file->pirvate_data*/ -struct mei_cl { - struct list_head link; - struct mei_device *dev; - enum file_state state; - wait_queue_head_t tx_wait; - wait_queue_head_t rx_wait; - wait_queue_head_t wait; - int read_pending; - int status; - /* ID of client connected */ - u8 host_client_id; - u8 me_client_id; - u8 mei_flow_ctrl_creds; - u8 timer_count; - enum mei_file_transaction_states reading_state; - enum mei_file_transaction_states writing_state; - int sm_state; - struct mei_cl_cb *read_cb; -}; - -struct mei_io_list { - struct mei_cl_cb mei_cb; -}; - -/* MEI private device struct */ -struct mei_device { - struct pci_dev *pdev; /* pointer to pci device struct */ - /* - * lists of queues - */ - /* array of pointers to aio lists */ - struct mei_io_list read_list; /* driver read queue */ - struct mei_io_list write_list; /* driver write queue */ - struct mei_io_list write_waiting_list; /* write waiting queue */ - struct mei_io_list ctrl_wr_list; /* managed write IOCTL list */ - struct mei_io_list ctrl_rd_list; /* managed read IOCTL list */ - struct mei_io_list amthi_cmd_list; /* amthi list for cmd waiting */ - - /* driver managed amthi list for reading completed amthi cmd data */ - struct mei_io_list amthi_read_complete_list; - /* - * list of files - */ - struct list_head file_list; - long open_handle_count; - /* - * memory of device - */ - unsigned int mem_base; - unsigned int mem_length; - void __iomem *mem_addr; - /* - * lock for the device - */ - struct mutex device_lock; /* device lock */ - struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ - bool recvd_msg; - /* - * hw states of host and fw(ME) - */ - u32 host_hw_state; - u32 me_hw_state; - /* - * waiting queue for receive message from FW - */ - wait_queue_head_t wait_recvd_msg; - wait_queue_head_t wait_stop_wd; - - /* - * mei device states - */ - enum mei_states mei_state; - enum mei_init_clients_states init_clients_state; - u16 init_clients_timer; - bool stop; - bool need_reset; - - u32 extra_write_index; - unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ - u32 wr_msg_buf[128]; /* used for control messages */ - u32 ext_msg_buf[8]; /* for control responses */ - u32 rd_msg_hdr; - - struct hbm_version version; - - struct mei_me_client *me_clients; /* Note: memory has to be allocated */ - DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); - DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - u8 me_clients_num; - u8 me_client_presentation_num; - u8 me_client_index; - bool mei_host_buffer_is_empty; - - struct mei_cl wd_cl; - bool wd_pending; - bool wd_stopped; - bool wd_bypass; /* if false, don't refresh watchdog ME client */ - u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ - u16 wd_due_counter; - unsigned char wd_data[MEI_START_WD_DATA_SIZE]; - - - - struct file *iamthif_file_object; - struct mei_cl iamthif_cl; - struct mei_cl_cb *iamthif_current_cb; - int iamthif_mtu; - unsigned long iamthif_timer; - u32 iamthif_stall_timer; - unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ - u32 iamthif_msg_buf_size; - u32 iamthif_msg_buf_index; - enum iamthif_states iamthif_state; - bool iamthif_flow_control_pending; - bool iamthif_ioctl; - bool iamthif_canceled; - - bool wd_interface_reg; -}; - - -/* - * mei init function prototypes - */ -struct mei_device *mei_device_init(struct pci_dev *pdev); -void mei_reset(struct mei_device *dev, int interrupts); -int mei_hw_init(struct mei_device *dev); -int mei_task_initialize_clients(void *data); -int mei_initialize_clients(struct mei_device *dev); -int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); -void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); -void mei_host_init_iamthif(struct mei_device *dev); -void mei_allocate_me_clients_storage(struct mei_device *dev); - - -u8 mei_find_me_client_update_filext(struct mei_device *dev, - struct mei_cl *priv, - const uuid_le *cguid, u8 client_id); - -/* - * MEI IO List Functions - */ -void mei_io_list_init(struct mei_io_list *list); -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl); - -/* - * MEI ME Client Functions - */ - -struct mei_cl *mei_cl_allocate(struct mei_device *dev); -void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); -int mei_cl_flush_queues(struct mei_cl *cl); -/** - * mei_cl_cmp_id - tells if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns true - if ids are the same and not NULL - */ -static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, - const struct mei_cl *cl2) -{ - return cl1 && cl2 && - (cl1->host_client_id == cl2->host_client_id) && - (cl1->me_client_id == cl2->me_client_id); -} - - - -/* - * MEI Host Client Functions - */ -void mei_host_start_message(struct mei_device *dev); -void mei_host_enum_clients_message(struct mei_device *dev); -int mei_host_client_properties(struct mei_device *dev); - -/* - * MEI interrupt functions prototype - */ -irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id); -irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id); -void mei_timer(struct work_struct *work); - -/* - * MEI input output function prototype - */ -int mei_ioctl_connect_client(struct file *file, - struct mei_connect_client_data *data); - -int mei_start_read(struct mei_device *dev, struct mei_cl *cl); - -int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); - -int amthi_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset); - -struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, - struct file *file); - -void mei_run_next_iamthif_cmd(struct mei_device *dev); - -void mei_free_cb_private(struct mei_cl_cb *priv_cb); - -int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid); - -/* - * Register Access Function - */ - -/** - * mei_reg_read - Reads 32bit data from the mei device - * - * @dev: the device structure - * @offset: offset from which to read the data - * - * returns register value (u32) - */ -static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset) -{ - return ioread32(dev->mem_addr + offset); -} - -/** - * mei_reg_write - Writes 32bit data to the mei device - * - * @dev: the device structure - * @offset: offset from which to write the data - * @value: register value to write (u32) - */ -static inline void mei_reg_write(struct mei_device *dev, - unsigned long offset, u32 value) -{ - iowrite32(value, dev->mem_addr + offset); -} - -/** - * mei_hcsr_read - Reads 32bit data from the host CSR - * - * @dev: the device structure - * - * returns the byte read. - */ -static inline u32 mei_hcsr_read(struct mei_device *dev) -{ - return mei_reg_read(dev, H_CSR); -} - -/** - * mei_mecsr_read - Reads 32bit data from the ME CSR - * - * @dev: the device structure - * - * returns ME_CSR_HA register value (u32) - */ -static inline u32 mei_mecsr_read(struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CSR_HA); -} - -/** - * get_me_cb_rw - Reads 32bit data from the mei ME_CB_RW register - * - * @dev: the device structure - * - * returns ME_CB_RW register value (u32) - */ -static inline u32 mei_mecbrw_read(struct mei_device *dev) -{ - return mei_reg_read(dev, ME_CB_RW); -} - - -/* - * mei interface function prototypes - */ -void mei_hcsr_set(struct mei_device *dev); -void mei_csr_clear_his(struct mei_device *dev); - -void mei_enable_interrupts(struct mei_device *dev); -void mei_disable_interrupts(struct mei_device *dev); - -#endif diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c deleted file mode 100644 index cf4c29d..0000000 --- a/drivers/staging/mei/wd.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2003-2012, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> -#include <linux/pci.h> -#include <linux/sched.h> -#include <linux/watchdog.h> - -#include "mei_dev.h" -#include "hw.h" -#include "interface.h" -#include "mei.h" - -static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; -static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; - -const u8 mei_wd_state_independence_msg[3][4] = { - {0x05, 0x02, 0x51, 0x10}, - {0x05, 0x02, 0x52, 0x10}, - {0x07, 0x02, 0x01, 0x10} -}; - -/* - * AMT Watchdog Device - */ -#define INTEL_AMT_WATCHDOG_ID "INTCAMT" - -/* UUIDs for AMT F/W clients */ -const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89, - 0x9D, 0xA9, 0x15, 0x14, 0xCB, - 0x32, 0xAB); - -void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) -{ - dev_dbg(&dev->pdev->dev, "timeout=%d.\n", timeout); - memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE); - memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, - &timeout, sizeof(u16)); -} - -/** - * host_init_wd - mei initialization wd. - * - * @dev: the device structure - */ -bool mei_wd_host_init(struct mei_device *dev) -{ - bool ret = false; - - mei_cl_init(&dev->wd_cl, dev); - - /* look for WD client and connect to it */ - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT; - - /* find ME WD client */ - mei_find_me_client_update_filext(dev, &dev->wd_cl, - &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); - - dev_dbg(&dev->pdev->dev, "check wd_cl\n"); - if (MEI_FILE_CONNECTING == dev->wd_cl.state) { - if (mei_connect(dev, &dev->wd_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to WD client\n"); - dev->wd_cl.state = MEI_FILE_DISCONNECTED; - dev->wd_cl.host_client_id = 0; - ret = false; - goto end; - } else { - dev->wd_cl.timer_count = CONNECT_TIMEOUT; - } - } else { - dev_dbg(&dev->pdev->dev, "Failed to find WD client\n"); - ret = false; - goto end; - } - -end: - return ret; -} - -/** - * mei_wd_send - sends watch dog message to fw. - * - * @dev: the device structure - * - * returns 0 if success, - * -EIO when message send fails - * -EINVAL when invalid message is to be sent - */ -int mei_wd_send(struct mei_device *dev) -{ - struct mei_msg_hdr *mei_hdr; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = dev->wd_cl.host_client_id; - mei_hdr->me_addr = dev->wd_cl.me_client_id; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE)) - mei_hdr->length = MEI_START_WD_DATA_SIZE; - else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE)) - mei_hdr->length = MEI_WD_PARAMS_SIZE; - else - return -EINVAL; - - return mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length); -} - -/** - * mei_wd_stop - sends watchdog stop message to fw. - * - * @dev: the device structure - * @preserve: indicate if to keep the timeout value - * - * returns 0 if success, - * -EIO when message send fails - * -EINVAL when invalid message is to be sent - */ -int mei_wd_stop(struct mei_device *dev, bool preserve) -{ - int ret; - u16 wd_timeout = dev->wd_timeout; - - cancel_delayed_work(&dev->timer_work); - if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout) - return 0; - - dev->wd_timeout = 0; - dev->wd_due_counter = 0; - memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE); - dev->stop = true; - - ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); - if (ret < 0) - goto out; - - if (ret && dev->mei_host_buffer_is_empty) { - ret = 0; - dev->mei_host_buffer_is_empty = false; - - if (!mei_wd_send(dev)) { - ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); - if (ret) - goto out; - } else { - dev_dbg(&dev->pdev->dev, "send stop WD failed\n"); - } - - dev->wd_pending = false; - } else { - dev->wd_pending = true; - } - dev->wd_stopped = false; - mutex_unlock(&dev->device_lock); - - ret = wait_event_interruptible_timeout(dev->wait_stop_wd, - dev->wd_stopped, 10 * HZ); - mutex_lock(&dev->device_lock); - if (dev->wd_stopped) { - dev_dbg(&dev->pdev->dev, "stop wd complete ret=%d.\n", ret); - ret = 0; - } else { - if (!ret) - ret = -ETIMEDOUT; - dev_warn(&dev->pdev->dev, - "stop wd failed to complete ret=%d.\n", ret); - } - - if (preserve) - dev->wd_timeout = wd_timeout; - -out: - return ret; -} - -/* - * mei_wd_ops_start - wd start command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_start(struct watchdog_device *wd_dev) -{ - int err = -ENODEV; - struct mei_device *dev; - - dev = pci_get_drvdata(mei_device); - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - - if (dev->mei_state != MEI_ENABLED) { - dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n", - dev->mei_state); - goto end_unlock; - } - - if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, "MEI Driver is not connected to Watchdog Client\n"); - goto end_unlock; - } - - mei_wd_set_start_timeout(dev, dev->wd_timeout); - - err = 0; -end_unlock: - mutex_unlock(&dev->device_lock); - return err; -} - -/* - * mei_wd_ops_stop - wd stop command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_stop(struct watchdog_device *wd_dev) -{ - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - mei_wd_stop(dev, false); - mutex_unlock(&dev->device_lock); - - return 0; -} - -/* - * mei_wd_ops_ping - wd ping command from the watchdog core. - * - * @wd_dev - watchdog device struct - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_ping(struct watchdog_device *wd_dev) -{ - int ret = 0; - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - mutex_lock(&dev->device_lock); - - if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, "wd is not connected.\n"); - ret = -ENODEV; - goto end; - } - - /* Check if we can send the ping to HW*/ - if (dev->mei_host_buffer_is_empty && - mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { - - dev->mei_host_buffer_is_empty = false; - dev_dbg(&dev->pdev->dev, "sending watchdog ping\n"); - - if (mei_wd_send(dev)) { - dev_dbg(&dev->pdev->dev, "wd send failed.\n"); - ret = -EIO; - goto end; - } - - if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) { - dev_dbg(&dev->pdev->dev, "mei_flow_ctrl_reduce() failed.\n"); - ret = -EIO; - goto end; - } - - } else { - dev->wd_pending = true; - } - -end: - mutex_unlock(&dev->device_lock); - return ret; -} - -/* - * mei_wd_ops_set_timeout - wd set timeout command from the watchdog core. - * - * @wd_dev - watchdog device struct - * @timeout - timeout value to set - * - * returns 0 if success, negative errno code for failure - */ -static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout) -{ - struct mei_device *dev; - dev = pci_get_drvdata(mei_device); - - if (!dev) - return -ENODEV; - - /* Check Timeout value */ - if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT) - return -EINVAL; - - mutex_lock(&dev->device_lock); - - dev->wd_timeout = timeout; - wd_dev->timeout = timeout; - mei_wd_set_start_timeout(dev, dev->wd_timeout); - - mutex_unlock(&dev->device_lock); - - return 0; -} - -/* - * Watchdog Device structs - */ -static const struct watchdog_ops wd_ops = { - .owner = THIS_MODULE, - .start = mei_wd_ops_start, - .stop = mei_wd_ops_stop, - .ping = mei_wd_ops_ping, - .set_timeout = mei_wd_ops_set_timeout, -}; -static const struct watchdog_info wd_info = { - .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, -}; - -struct watchdog_device amt_wd_dev = { - .info = &wd_info, - .ops = &wd_ops, - .timeout = AMT_WD_DEFAULT_TIMEOUT, - .min_timeout = AMT_WD_MIN_TIMEOUT, - .max_timeout = AMT_WD_MAX_TIMEOUT, -}; - - -void mei_watchdog_register(struct mei_device *dev) -{ - dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout); - - dev->wd_due_counter = !!dev->wd_timeout; - - if (watchdog_register_device(&amt_wd_dev)) { - dev_err(&dev->pdev->dev, "unable to register watchdog device.\n"); - dev->wd_interface_reg = false; - } else { - dev_dbg(&dev->pdev->dev, "successfully register watchdog interface.\n"); - dev->wd_interface_reg = true; - } -} - -void mei_watchdog_unregister(struct mei_device *dev) -{ - if (dev->wd_interface_reg) - watchdog_unregister_device(&amt_wd_dev); - dev->wd_interface_reg = false; -} - diff --git a/drivers/staging/net/Kconfig b/drivers/staging/net/Kconfig new file mode 100644 index 0000000..a64e56b --- /dev/null +++ b/drivers/staging/net/Kconfig @@ -0,0 +1,38 @@ +if NETDEVICES + +if WAN + +config PC300 + tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)" + depends on HDLC && PCI && BROKEN + ---help--- + This driver is broken because of struct tty_driver change. + + Driver for the Cyclades-PC300 synchronous communication boards. + + These boards provide synchronous serial interfaces to your + Linux box (interfaces currently available are RS-232/V.35, X.21 and + T1/E1). If you wish to support Multilink PPP, please select the + option later and read the file README.mlppp provided by PC300 + package. + + To compile this as a module, choose M here: the module + will be called pc300. + + If unsure, say N. + +config PC300_MLPPP + bool "Cyclades-PC300 MLPPP support" + depends on PC300 && PPP_MULTILINK && PPP_SYNC_TTY && HDLC_PPP + help + Multilink PPP over the PC300 synchronous communication boards. + +comment "Cyclades-PC300 MLPPP support is disabled." + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + +comment "Refer to the file README.mlppp, provided by PC300 package." + depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP) + +endif # WAN + +endif # NETDEVICES diff --git a/drivers/staging/net/Makefile b/drivers/staging/net/Makefile new file mode 100644 index 0000000..0799c43 --- /dev/null +++ b/drivers/staging/net/Makefile @@ -0,0 +1,5 @@ +pc300-y := pc300_drv.o +pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o +pc300-objs := $(pc300-y) + +obj-$(CONFIG_PC300) += pc300.o diff --git a/drivers/staging/net/TODO b/drivers/staging/net/TODO new file mode 100644 index 0000000..e3446f2 --- /dev/null +++ b/drivers/staging/net/TODO @@ -0,0 +1,5 @@ +PC300 +The driver is very broken and cannot work with the current TTY layer. It is +inevitable to convert it to the new TTY API. + +If no one steps in to adopt the driver, it will be removed in the 3.7 release. diff --git a/drivers/staging/net/pc300-falc-lh.h b/drivers/staging/net/pc300-falc-lh.h new file mode 100644 index 0000000..01ed23c --- /dev/null +++ b/drivers/staging/net/pc300-falc-lh.h @@ -0,0 +1,1238 @@ +/* + * falc.h Description of the Siemens FALC T1/E1 framer. + * + * Author: Ivan Passos <ivan@cyclades.com> + * + * Copyright: (c) 2000-2001 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * $Log: falc-lh.h,v $ + * Revision 3.1 2001/06/15 12:41:10 regina + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:24:47 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 1.1 2000/05/15 ivan + * Included DJA bits for the LIM2 register. + * + * Revision 1.0 2000/02/22 ivan + * Initial version. + * + */ + +#ifndef _FALC_LH_H +#define _FALC_LH_H + +#define NUM_OF_T1_CHANNELS 24 +#define NUM_OF_E1_CHANNELS 32 + +/*>>>>>>>>>>>>>>>>> FALC Register Bits (Transmit Mode) <<<<<<<<<<<<<<<<<<< */ + +/* CMDR (Command Register) + ---------------- E1 & T1 ------------------------------ */ +#define CMDR_RMC 0x80 +#define CMDR_RRES 0x40 +#define CMDR_XREP 0x20 +#define CMDR_XRES 0x10 +#define CMDR_XHF 0x08 +#define CMDR_XTF 0x04 +#define CMDR_XME 0x02 +#define CMDR_SRES 0x01 + +/* MODE (Mode Register) + ----------------- E1 & T1 ----------------------------- */ +#define MODE_MDS2 0x80 +#define MODE_MDS1 0x40 +#define MODE_MDS0 0x20 +#define MODE_BRAC 0x10 +#define MODE_HRAC 0x08 + +/* IPC (Interrupt Port Configuration) + ----------------- E1 & T1 ----------------------------- */ +#define IPC_VIS 0x80 +#define IPC_SCI 0x04 +#define IPC_IC1 0x02 +#define IPC_IC0 0x01 + +/* CCR1 (Common Configuration Register 1) + ----------------- E1 & T1 ----------------------------- */ +#define CCR1_SFLG 0x80 +#define CCR1_XTS16RA 0x40 +#define CCR1_BRM 0x40 +#define CCR1_CASSYM 0x20 +#define CCR1_EDLX 0x20 +#define CCR1_EITS 0x10 +#define CCR1_ITF 0x08 +#define CCR1_RFT1 0x02 +#define CCR1_RFT0 0x01 + +/* CCR3 (Common Configuration Register 3) + ---------------- E1 & T1 ------------------------------ */ + +#define CCR3_PRE1 0x80 +#define CCR3_PRE0 0x40 +#define CCR3_EPT 0x20 +#define CCR3_RADD 0x10 +#define CCR3_RCRC 0x04 +#define CCR3_XCRC 0x02 + + +/* RTR1-4 (Receive Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define RTR1_TS0 0x80 +#define RTR1_TS1 0x40 +#define RTR1_TS2 0x20 +#define RTR1_TS3 0x10 +#define RTR1_TS4 0x08 +#define RTR1_TS5 0x04 +#define RTR1_TS6 0x02 +#define RTR1_TS7 0x01 + +#define RTR2_TS8 0x80 +#define RTR2_TS9 0x40 +#define RTR2_TS10 0x20 +#define RTR2_TS11 0x10 +#define RTR2_TS12 0x08 +#define RTR2_TS13 0x04 +#define RTR2_TS14 0x02 +#define RTR2_TS15 0x01 + +#define RTR3_TS16 0x80 +#define RTR3_TS17 0x40 +#define RTR3_TS18 0x20 +#define RTR3_TS19 0x10 +#define RTR3_TS20 0x08 +#define RTR3_TS21 0x04 +#define RTR3_TS22 0x02 +#define RTR3_TS23 0x01 + +#define RTR4_TS24 0x80 +#define RTR4_TS25 0x40 +#define RTR4_TS26 0x20 +#define RTR4_TS27 0x10 +#define RTR4_TS28 0x08 +#define RTR4_TS29 0x04 +#define RTR4_TS30 0x02 +#define RTR4_TS31 0x01 + + +/* TTR1-4 (Transmit Timeslot Register 1-4) + ---------------- E1 & T1 ------------------------------ */ + +#define TTR1_TS0 0x80 +#define TTR1_TS1 0x40 +#define TTR1_TS2 0x20 +#define TTR1_TS3 0x10 +#define TTR1_TS4 0x08 +#define TTR1_TS5 0x04 +#define TTR1_TS6 0x02 +#define TTR1_TS7 0x01 + +#define TTR2_TS8 0x80 +#define TTR2_TS9 0x40 +#define TTR2_TS10 0x20 +#define TTR2_TS11 0x10 +#define TTR2_TS12 0x08 +#define TTR2_TS13 0x04 +#define TTR2_TS14 0x02 +#define TTR2_TS15 0x01 + +#define TTR3_TS16 0x80 +#define TTR3_TS17 0x40 +#define TTR3_TS18 0x20 +#define TTR3_TS19 0x10 +#define TTR3_TS20 0x08 +#define TTR3_TS21 0x04 +#define TTR3_TS22 0x02 +#define TTR3_TS23 0x01 + +#define TTR4_TS24 0x80 +#define TTR4_TS25 0x40 +#define TTR4_TS26 0x20 +#define TTR4_TS27 0x10 +#define TTR4_TS28 0x08 +#define TTR4_TS29 0x04 +#define TTR4_TS30 0x02 +#define TTR4_TS31 0x01 + + + +/* IMR0-4 (Interrupt Mask Register 0-4) + + ----------------- E1 & T1 ----------------------------- */ + +#define IMR0_RME 0x80 +#define IMR0_RFS 0x40 +#define IMR0_T8MS 0x20 +#define IMR0_ISF 0x20 +#define IMR0_RMB 0x10 +#define IMR0_CASC 0x08 +#define IMR0_RSC 0x08 +#define IMR0_CRC6 0x04 +#define IMR0_CRC4 0x04 +#define IMR0_PDEN 0x02 +#define IMR0_RPF 0x01 + +#define IMR1_CASE 0x80 +#define IMR1_RDO 0x40 +#define IMR1_ALLS 0x20 +#define IMR1_XDU 0x10 +#define IMR1_XMB 0x08 +#define IMR1_XLSC 0x02 +#define IMR1_XPR 0x01 +#define IMR1_LLBSC 0x80 + +#define IMR2_FAR 0x80 +#define IMR2_LFA 0x40 +#define IMR2_MFAR 0x20 +#define IMR2_T400MS 0x10 +#define IMR2_LMFA 0x10 +#define IMR2_AIS 0x08 +#define IMR2_LOS 0x04 +#define IMR2_RAR 0x02 +#define IMR2_RA 0x01 + +#define IMR3_ES 0x80 +#define IMR3_SEC 0x40 +#define IMR3_LMFA16 0x20 +#define IMR3_AIS16 0x10 +#define IMR3_RA16 0x08 +#define IMR3_API 0x04 +#define IMR3_XSLP 0x20 +#define IMR3_XSLN 0x10 +#define IMR3_LLBSC 0x08 +#define IMR3_XRS 0x04 +#define IMR3_SLN 0x02 +#define IMR3_SLP 0x01 + +#define IMR4_LFA 0x80 +#define IMR4_FER 0x40 +#define IMR4_CER 0x20 +#define IMR4_AIS 0x10 +#define IMR4_LOS 0x08 +#define IMR4_CVE 0x04 +#define IMR4_SLIP 0x02 +#define IMR4_EBE 0x01 + +/* FMR0-5 for E1 and T1 (Framer Mode Register ) */ + +#define FMR0_XC1 0x80 +#define FMR0_XC0 0x40 +#define FMR0_RC1 0x20 +#define FMR0_RC0 0x10 +#define FMR0_EXTD 0x08 +#define FMR0_ALM 0x04 +#define E1_FMR0_FRS 0x02 +#define T1_FMR0_FRS 0x08 +#define FMR0_SRAF 0x04 +#define FMR0_EXLS 0x02 +#define FMR0_SIM 0x01 + +#define FMR1_MFCS 0x80 +#define FMR1_AFR 0x40 +#define FMR1_ENSA 0x20 +#define FMR1_CTM 0x80 +#define FMR1_SIGM 0x40 +#define FMR1_EDL 0x20 +#define FMR1_PMOD 0x10 +#define FMR1_XFS 0x08 +#define FMR1_CRC 0x08 +#define FMR1_ECM 0x04 +#define FMR1_IMOD 0x02 +#define FMR1_XAIS 0x01 + +#define FMR2_RFS1 0x80 +#define FMR2_RFS0 0x40 +#define FMR2_MCSP 0x40 +#define FMR2_RTM 0x20 +#define FMR2_SSP 0x20 +#define FMR2_DAIS 0x10 +#define FMR2_SAIS 0x08 +#define FMR2_PLB 0x04 +#define FMR2_AXRA 0x02 +#define FMR2_ALMF 0x01 +#define FMR2_EXZE 0x01 + +#define LOOP_RTM 0x40 +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA 0x1f + +/*--------------------- E1 ----------------------------*/ +#define FMR3_XLD 0x20 +#define FMR3_XLU 0x10 + +/*--------------------- T1 ----------------------------*/ +#define FMR4_AIS3 0x80 +#define FMR4_TM 0x40 +#define FMR4_XRA 0x20 +#define FMR4_SSC1 0x10 +#define FMR4_SSC0 0x08 +#define FMR4_AUTO 0x04 +#define FMR4_FM1 0x02 +#define FMR4_FM0 0x01 + +#define FMR5_SRS 0x80 +#define FMR5_EIBR 0x40 +#define FMR5_XLD 0x20 +#define FMR5_XLU 0x10 + + +/* LOOP (Channel Loop Back) + + ------------------ E1 & T1 ---------------------------- */ + +#define LOOP_SFM 0x40 +#define LOOP_ECLB 0x20 +#define LOOP_CLA4 0x10 +#define LOOP_CLA3 0x08 +#define LOOP_CLA2 0x04 +#define LOOP_CLA1 0x02 +#define LOOP_CLA0 0x01 + + + +/* XSW (Transmit Service Word Pulseframe) + + ------------------- E1 --------------------------- */ + +#define XSW_XSIS 0x80 +#define XSW_XTM 0x40 +#define XSW_XRA 0x20 +#define XSW_XY0 0x10 +#define XSW_XY1 0x08 +#define XSW_XY2 0x04 +#define XSW_XY3 0x02 +#define XSW_XY4 0x01 + + +/* XSP (Transmit Spare Bits) + + ------------------- E1 --------------------------- */ + +#define XSP_XAP 0x80 +#define XSP_CASEN 0x40 +#define XSP_TT0 0x20 +#define XSP_EBP 0x10 +#define XSP_AXS 0x08 +#define XSP_XSIF 0x04 +#define XSP_XS13 0x02 +#define XSP_XS15 0x01 + + +/* XC0/1 (Transmit Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define XC0_SA8E 0x80 +#define XC0_SA7E 0x40 +#define XC0_SA6E 0x20 +#define XC0_SA5E 0x10 +#define XC0_SA4E 0x08 +#define XC0_BRM 0x80 +#define XC0_MFBS 0x40 +#define XC0_SFRZ 0x10 +#define XC0_XCO2 0x04 +#define XC0_XCO1 0x02 +#define XC0_XCO0 0x01 + +#define XC1_XTO5 0x20 +#define XC1_XTO4 0x10 +#define XC1_XTO3 0x08 +#define XC1_XTO2 0x04 +#define XC1_XTO1 0x02 +#define XC1_XTO0 0x01 + + +/* RC0/1 (Receive Control 0/1) + ------------------ E1 & T1 ---------------------------- */ + +#define RC0_SICS 0x40 +#define RC0_CRCI 0x20 +#define RC0_XCRCI 0x10 +#define RC0_RDIS 0x08 +#define RC0_RCO2 0x04 +#define RC0_RCO1 0x02 +#define RC0_RCO0 0x01 + +#define RC1_SWD 0x80 +#define RC1_ASY4 0x40 +#define RC1_RRAM 0x40 +#define RC1_RTO5 0x20 +#define RC1_RTO4 0x10 +#define RC1_RTO3 0x08 +#define RC1_RTO2 0x04 +#define RC1_RTO1 0x02 +#define RC1_RTO0 0x01 + + + +/* XPM0-2 (Transmit Pulse Mask 0-2) + --------------------- E1 & T1 ------------------------- */ + +#define XPM0_XP12 0x80 +#define XPM0_XP11 0x40 +#define XPM0_XP10 0x20 +#define XPM0_XP04 0x10 +#define XPM0_XP03 0x08 +#define XPM0_XP02 0x04 +#define XPM0_XP01 0x02 +#define XPM0_XP00 0x01 + +#define XPM1_XP30 0x80 +#define XPM1_XP24 0x40 +#define XPM1_XP23 0x20 +#define XPM1_XP22 0x10 +#define XPM1_XP21 0x08 +#define XPM1_XP20 0x04 +#define XPM1_XP14 0x02 +#define XPM1_XP13 0x01 + +#define XPM2_XLHP 0x80 +#define XPM2_XLT 0x40 +#define XPM2_DAXLT 0x20 +#define XPM2_XP34 0x08 +#define XPM2_XP33 0x04 +#define XPM2_XP32 0x02 +#define XPM2_XP31 0x01 + + +/* TSWM (Transparent Service Word Mask) + ------------------ E1 ---------------------------- */ + +#define TSWM_TSIS 0x80 +#define TSWM_TSIF 0x40 +#define TSWM_TRA 0x20 +#define TSWM_TSA4 0x10 +#define TSWM_TSA5 0x08 +#define TSWM_TSA6 0x04 +#define TSWM_TSA7 0x02 +#define TSWM_TSA8 0x01 + +/* IDLE <Idle Channel Code Register> + + ------------------ E1 & T1 ----------------------- */ + +#define IDLE_IDL7 0x80 +#define IDLE_IDL6 0x40 +#define IDLE_IDL5 0x20 +#define IDLE_IDL4 0x10 +#define IDLE_IDL3 0x08 +#define IDLE_IDL2 0x04 +#define IDLE_IDL1 0x02 +#define IDLE_IDL0 0x01 + + +/* XSA4-8 <Transmit SA4-8 Register(Read/Write) > + -------------------E1 ----------------------------- */ + +#define XSA4_XS47 0x80 +#define XSA4_XS46 0x40 +#define XSA4_XS45 0x20 +#define XSA4_XS44 0x10 +#define XSA4_XS43 0x08 +#define XSA4_XS42 0x04 +#define XSA4_XS41 0x02 +#define XSA4_XS40 0x01 + +#define XSA5_XS57 0x80 +#define XSA5_XS56 0x40 +#define XSA5_XS55 0x20 +#define XSA5_XS54 0x10 +#define XSA5_XS53 0x08 +#define XSA5_XS52 0x04 +#define XSA5_XS51 0x02 +#define XSA5_XS50 0x01 + +#define XSA6_XS67 0x80 +#define XSA6_XS66 0x40 +#define XSA6_XS65 0x20 +#define XSA6_XS64 0x10 +#define XSA6_XS63 0x08 +#define XSA6_XS62 0x04 +#define XSA6_XS61 0x02 +#define XSA6_XS60 0x01 + +#define XSA7_XS77 0x80 +#define XSA7_XS76 0x40 +#define XSA7_XS75 0x20 +#define XSA7_XS74 0x10 +#define XSA7_XS73 0x08 +#define XSA7_XS72 0x04 +#define XSA7_XS71 0x02 +#define XSA7_XS70 0x01 + +#define XSA8_XS87 0x80 +#define XSA8_XS86 0x40 +#define XSA8_XS85 0x20 +#define XSA8_XS84 0x10 +#define XSA8_XS83 0x08 +#define XSA8_XS82 0x04 +#define XSA8_XS81 0x02 +#define XSA8_XS80 0x01 + + +/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write)) + ----------------------- T1 --------------------- */ + +#define XDL1_XDL17 0x80 +#define XDL1_XDL16 0x40 +#define XDL1_XDL15 0x20 +#define XDL1_XDL14 0x10 +#define XDL1_XDL13 0x08 +#define XDL1_XDL12 0x04 +#define XDL1_XDL11 0x02 +#define XDL1_XDL10 0x01 + +#define XDL2_XDL27 0x80 +#define XDL2_XDL26 0x40 +#define XDL2_XDL25 0x20 +#define XDL2_XDL24 0x10 +#define XDL2_XDL23 0x08 +#define XDL2_XDL22 0x04 +#define XDL2_XDL21 0x02 +#define XDL2_XDL20 0x01 + +#define XDL3_XDL37 0x80 +#define XDL3_XDL36 0x40 +#define XDL3_XDL35 0x20 +#define XDL3_XDL34 0x10 +#define XDL3_XDL33 0x08 +#define XDL3_XDL32 0x04 +#define XDL3_XDL31 0x02 +#define XDL3_XDL30 0x01 + + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ E1 ---------------------------- */ + +#define E1_ICB1_IC0 0x80 +#define E1_ICB1_IC1 0x40 +#define E1_ICB1_IC2 0x20 +#define E1_ICB1_IC3 0x10 +#define E1_ICB1_IC4 0x08 +#define E1_ICB1_IC5 0x04 +#define E1_ICB1_IC6 0x02 +#define E1_ICB1_IC7 0x01 + +#define E1_ICB2_IC8 0x80 +#define E1_ICB2_IC9 0x40 +#define E1_ICB2_IC10 0x20 +#define E1_ICB2_IC11 0x10 +#define E1_ICB2_IC12 0x08 +#define E1_ICB2_IC13 0x04 +#define E1_ICB2_IC14 0x02 +#define E1_ICB2_IC15 0x01 + +#define E1_ICB3_IC16 0x80 +#define E1_ICB3_IC17 0x40 +#define E1_ICB3_IC18 0x20 +#define E1_ICB3_IC19 0x10 +#define E1_ICB3_IC20 0x08 +#define E1_ICB3_IC21 0x04 +#define E1_ICB3_IC22 0x02 +#define E1_ICB3_IC23 0x01 + +#define E1_ICB4_IC24 0x80 +#define E1_ICB4_IC25 0x40 +#define E1_ICB4_IC26 0x20 +#define E1_ICB4_IC27 0x10 +#define E1_ICB4_IC28 0x08 +#define E1_ICB4_IC29 0x04 +#define E1_ICB4_IC30 0x02 +#define E1_ICB4_IC31 0x01 + +/* ICB1-4 (Idle Channel Register 1-4) + ------------------ T1 ---------------------------- */ + +#define T1_ICB1_IC1 0x80 +#define T1_ICB1_IC2 0x40 +#define T1_ICB1_IC3 0x20 +#define T1_ICB1_IC4 0x10 +#define T1_ICB1_IC5 0x08 +#define T1_ICB1_IC6 0x04 +#define T1_ICB1_IC7 0x02 +#define T1_ICB1_IC8 0x01 + +#define T1_ICB2_IC9 0x80 +#define T1_ICB2_IC10 0x40 +#define T1_ICB2_IC11 0x20 +#define T1_ICB2_IC12 0x10 +#define T1_ICB2_IC13 0x08 +#define T1_ICB2_IC14 0x04 +#define T1_ICB2_IC15 0x02 +#define T1_ICB2_IC16 0x01 + +#define T1_ICB3_IC17 0x80 +#define T1_ICB3_IC18 0x40 +#define T1_ICB3_IC19 0x20 +#define T1_ICB3_IC20 0x10 +#define T1_ICB3_IC21 0x08 +#define T1_ICB3_IC22 0x04 +#define T1_ICB3_IC23 0x02 +#define T1_ICB3_IC24 0x01 + +/* FMR3 (Framer Mode Register 3) + --------------------E1------------------------ */ + +#define FMR3_CMI 0x08 +#define FMR3_SYNSA 0x04 +#define FMR3_CFRZ 0x02 +#define FMR3_EXTIW 0x01 + + + +/* CCB1-3 (Clear Channel Register) + ------------------- T1 ----------------------- */ + +#define CCB1_CH1 0x80 +#define CCB1_CH2 0x40 +#define CCB1_CH3 0x20 +#define CCB1_CH4 0x10 +#define CCB1_CH5 0x08 +#define CCB1_CH6 0x04 +#define CCB1_CH7 0x02 +#define CCB1_CH8 0x01 + +#define CCB2_CH9 0x80 +#define CCB2_CH10 0x40 +#define CCB2_CH11 0x20 +#define CCB2_CH12 0x10 +#define CCB2_CH13 0x08 +#define CCB2_CH14 0x04 +#define CCB2_CH15 0x02 +#define CCB2_CH16 0x01 + +#define CCB3_CH17 0x80 +#define CCB3_CH18 0x40 +#define CCB3_CH19 0x20 +#define CCB3_CH20 0x10 +#define CCB3_CH21 0x08 +#define CCB3_CH22 0x04 +#define CCB3_CH23 0x02 +#define CCB3_CH24 0x01 + + +/* LIM0/1 (Line Interface Mode 0/1) + ------------------- E1 & T1 --------------------------- */ + +#define LIM0_XFB 0x80 +#define LIM0_XDOS 0x40 +#define LIM0_SCL1 0x20 +#define LIM0_SCL0 0x10 +#define LIM0_EQON 0x08 +#define LIM0_ELOS 0x04 +#define LIM0_LL 0x02 +#define LIM0_MAS 0x01 + +#define LIM1_EFSC 0x80 +#define LIM1_RIL2 0x40 +#define LIM1_RIL1 0x20 +#define LIM1_RIL0 0x10 +#define LIM1_DCOC 0x08 +#define LIM1_JATT 0x04 +#define LIM1_RL 0x02 +#define LIM1_DRS 0x01 + + +/* PCDR (Pulse Count Detection Register(Read/Write)) + ------------------ E1 & T1 ------------------------- */ + +#define PCDR_PCD7 0x80 +#define PCDR_PCD6 0x40 +#define PCDR_PCD5 0x20 +#define PCDR_PCD4 0x10 +#define PCDR_PCD3 0x08 +#define PCDR_PCD2 0x04 +#define PCDR_PCD1 0x02 +#define PCDR_PCD0 0x01 + +#define PCRR_PCR7 0x80 +#define PCRR_PCR6 0x40 +#define PCRR_PCR5 0x20 +#define PCRR_PCR4 0x10 +#define PCRR_PCR3 0x08 +#define PCRR_PCR2 0x04 +#define PCRR_PCR1 0x02 +#define PCRR_PCR0 0x01 + + +/* LIM2 (Line Interface Mode 2) + + ------------------ E1 & T1 ---------------------------- */ + +#define LIM2_DJA2 0x20 +#define LIM2_DJA1 0x10 +#define LIM2_LOS2 0x02 +#define LIM2_LOS1 0x01 + +/* LCR1 (Loop Code Register 1) */ + +#define LCR1_EPRM 0x80 +#define LCR1_XPRBS 0x40 + +/* SIC1 (System Interface Control 1) */ +#define SIC1_SRSC 0x80 +#define SIC1_RBS1 0x20 +#define SIC1_RBS0 0x10 +#define SIC1_SXSC 0x08 +#define SIC1_XBS1 0x02 +#define SIC1_XBS0 0x01 + +/* DEC (Disable Error Counter) + ------------------ E1 & T1 ---------------------------- */ + +#define DEC_DCEC3 0x20 +#define DEC_DBEC 0x10 +#define DEC_DCEC1 0x08 +#define DEC_DCEC 0x08 +#define DEC_DEBC 0x04 +#define DEC_DCVC 0x02 +#define DEC_DFEC 0x01 + + +/* FALC Register Bits (Receive Mode) + ---------------------------------------------------------------------------- */ + + +/* FRS0/1 (Framer Receive Status Register 0/1) + ----------------- E1 & T1 ---------------------------------- */ + +#define FRS0_LOS 0x80 +#define FRS0_AIS 0x40 +#define FRS0_LFA 0x20 +#define FRS0_RRA 0x10 +#define FRS0_API 0x08 +#define FRS0_NMF 0x04 +#define FRS0_LMFA 0x02 +#define FRS0_FSRF 0x01 + +#define FRS1_TS16RA 0x40 +#define FRS1_TS16LOS 0x20 +#define FRS1_TS16AIS 0x10 +#define FRS1_TS16LFA 0x08 +#define FRS1_EXZD 0x80 +#define FRS1_LLBDD 0x10 +#define FRS1_LLBAD 0x08 +#define FRS1_XLS 0x02 +#define FRS1_XLO 0x01 +#define FRS1_PDEN 0x40 + +/* FRS2/3 (Framer Receive Status Register 2/3) + ----------------- T1 ---------------------------------- */ + +#define FRS2_ESC2 0x80 +#define FRS2_ESC1 0x40 +#define FRS2_ESC0 0x20 + +#define FRS3_FEH5 0x20 +#define FRS3_FEH4 0x10 +#define FRS3_FEH3 0x08 +#define FRS3_FEH2 0x04 +#define FRS3_FEH1 0x02 +#define FRS3_FEH0 0x01 + + +/* RSW (Receive Service Word Pulseframe) + ----------------- E1 ------------------------------ */ + +#define RSW_RSI 0x80 +#define RSW_RRA 0x20 +#define RSW_RYO 0x10 +#define RSW_RY1 0x08 +#define RSW_RY2 0x04 +#define RSW_RY3 0x02 +#define RSW_RY4 0x01 + + +/* RSP (Receive Spare Bits / Additional Status) + ---------------- E1 ------------------------------- */ + +#define RSP_SI1 0x80 +#define RSP_SI2 0x40 +#define RSP_LLBDD 0x10 +#define RSP_LLBAD 0x08 +#define RSP_RSIF 0x04 +#define RSP_RS13 0x02 +#define RSP_RS15 0x01 + + +/* FECL (Framing Error Counter) + ---------------- E1 & T1 -------------------------- */ + +#define FECL_FE7 0x80 +#define FECL_FE6 0x40 +#define FECL_FE5 0x20 +#define FECL_FE4 0x10 +#define FECL_FE3 0x08 +#define FECL_FE2 0x04 +#define FECL_FE1 0x02 +#define FECL_FE0 0x01 + +#define FECH_FE15 0x80 +#define FECH_FE14 0x40 +#define FECH_FE13 0x20 +#define FECH_FE12 0x10 +#define FECH_FE11 0x08 +#define FECH_FE10 0x04 +#define FECH_FE9 0x02 +#define FECH_FE8 0x01 + + +/* CVCl (Code Violation Counter) + ----------------- E1 ------------------------- */ + +#define CVCL_CV7 0x80 +#define CVCL_CV6 0x40 +#define CVCL_CV5 0x20 +#define CVCL_CV4 0x10 +#define CVCL_CV3 0x08 +#define CVCL_CV2 0x04 +#define CVCL_CV1 0x02 +#define CVCL_CV0 0x01 + +#define CVCH_CV15 0x80 +#define CVCH_CV14 0x40 +#define CVCH_CV13 0x20 +#define CVCH_CV12 0x10 +#define CVCH_CV11 0x08 +#define CVCH_CV10 0x04 +#define CVCH_CV9 0x02 +#define CVCH_CV8 0x01 + + +/* CEC1-3L (CRC Error Counter) + ------------------ E1 ----------------------------- */ + +#define CEC1L_CR7 0x80 +#define CEC1L_CR6 0x40 +#define CEC1L_CR5 0x20 +#define CEC1L_CR4 0x10 +#define CEC1L_CR3 0x08 +#define CEC1L_CR2 0x04 +#define CEC1L_CR1 0x02 +#define CEC1L_CR0 0x01 + +#define CEC1H_CR15 0x80 +#define CEC1H_CR14 0x40 +#define CEC1H_CR13 0x20 +#define CEC1H_CR12 0x10 +#define CEC1H_CR11 0x08 +#define CEC1H_CR10 0x04 +#define CEC1H_CR9 0x02 +#define CEC1H_CR8 0x01 + +#define CEC2L_CR7 0x80 +#define CEC2L_CR6 0x40 +#define CEC2L_CR5 0x20 +#define CEC2L_CR4 0x10 +#define CEC2L_CR3 0x08 +#define CEC2L_CR2 0x04 +#define CEC2L_CR1 0x02 +#define CEC2L_CR0 0x01 + +#define CEC2H_CR15 0x80 +#define CEC2H_CR14 0x40 +#define CEC2H_CR13 0x20 +#define CEC2H_CR12 0x10 +#define CEC2H_CR11 0x08 +#define CEC2H_CR10 0x04 +#define CEC2H_CR9 0x02 +#define CEC2H_CR8 0x01 + +#define CEC3L_CR7 0x80 +#define CEC3L_CR6 0x40 +#define CEC3L_CR5 0x20 +#define CEC3L_CR4 0x10 +#define CEC3L_CR3 0x08 +#define CEC3L_CR2 0x04 +#define CEC3L_CR1 0x02 +#define CEC3L_CR0 0x01 + +#define CEC3H_CR15 0x80 +#define CEC3H_CR14 0x40 +#define CEC3H_CR13 0x20 +#define CEC3H_CR12 0x10 +#define CEC3H_CR11 0x08 +#define CEC3H_CR10 0x04 +#define CEC3H_CR9 0x02 +#define CEC3H_CR8 0x01 + + +/* CECL (CRC Error Counter) + + ------------------ T1 ----------------------------- */ + +#define CECL_CR7 0x80 +#define CECL_CR6 0x40 +#define CECL_CR5 0x20 +#define CECL_CR4 0x10 +#define CECL_CR3 0x08 +#define CECL_CR2 0x04 +#define CECL_CR1 0x02 +#define CECL_CR0 0x01 + +#define CECH_CR15 0x80 +#define CECH_CR14 0x40 +#define CECH_CR13 0x20 +#define CECH_CR12 0x10 +#define CECH_CR11 0x08 +#define CECH_CR10 0x04 +#define CECH_CR9 0x02 +#define CECH_CR8 0x01 + +/* EBCL (E Bit Error Counter) + ------------------- E1 & T1 ------------------------- */ + +#define EBCL_EB7 0x80 +#define EBCL_EB6 0x40 +#define EBCL_EB5 0x20 +#define EBCL_EB4 0x10 +#define EBCL_EB3 0x08 +#define EBCL_EB2 0x04 +#define EBCL_EB1 0x02 +#define EBCL_EB0 0x01 + +#define EBCH_EB15 0x80 +#define EBCH_EB14 0x40 +#define EBCH_EB13 0x20 +#define EBCH_EB12 0x10 +#define EBCH_EB11 0x08 +#define EBCH_EB10 0x04 +#define EBCH_EB9 0x02 +#define EBCH_EB8 0x01 + + +/* RSA4-8 (Receive Sa4-8-Bit Register) + -------------------- E1 --------------------------- */ + +#define RSA4_RS47 0x80 +#define RSA4_RS46 0x40 +#define RSA4_RS45 0x20 +#define RSA4_RS44 0x10 +#define RSA4_RS43 0x08 +#define RSA4_RS42 0x04 +#define RSA4_RS41 0x02 +#define RSA4_RS40 0x01 + +#define RSA5_RS57 0x80 +#define RSA5_RS56 0x40 +#define RSA5_RS55 0x20 +#define RSA5_RS54 0x10 +#define RSA5_RS53 0x08 +#define RSA5_RS52 0x04 +#define RSA5_RS51 0x02 +#define RSA5_RS50 0x01 + +#define RSA6_RS67 0x80 +#define RSA6_RS66 0x40 +#define RSA6_RS65 0x20 +#define RSA6_RS64 0x10 +#define RSA6_RS63 0x08 +#define RSA6_RS62 0x04 +#define RSA6_RS61 0x02 +#define RSA6_RS60 0x01 + +#define RSA7_RS77 0x80 +#define RSA7_RS76 0x40 +#define RSA7_RS75 0x20 +#define RSA7_RS74 0x10 +#define RSA7_RS73 0x08 +#define RSA7_RS72 0x04 +#define RSA7_RS71 0x02 +#define RSA7_RS70 0x01 + +#define RSA8_RS87 0x80 +#define RSA8_RS86 0x40 +#define RSA8_RS85 0x20 +#define RSA8_RS84 0x10 +#define RSA8_RS83 0x08 +#define RSA8_RS82 0x04 +#define RSA8_RS81 0x02 +#define RSA8_RS80 0x01 + +/* RSA6S (Receive Sa6 Bit Status Register) + ------------------------ T1 ------------------------- */ + +#define RSA6S_SX 0x20 +#define RSA6S_SF 0x10 +#define RSA6S_SE 0x08 +#define RSA6S_SC 0x04 +#define RSA6S_SA 0x02 +#define RSA6S_S8 0x01 + + +/* RDL1-3 Receive DL-Bit Register1-3) + ------------------------ T1 ------------------------- */ + +#define RDL1_RDL17 0x80 +#define RDL1_RDL16 0x40 +#define RDL1_RDL15 0x20 +#define RDL1_RDL14 0x10 +#define RDL1_RDL13 0x08 +#define RDL1_RDL12 0x04 +#define RDL1_RDL11 0x02 +#define RDL1_RDL10 0x01 + +#define RDL2_RDL27 0x80 +#define RDL2_RDL26 0x40 +#define RDL2_RDL25 0x20 +#define RDL2_RDL24 0x10 +#define RDL2_RDL23 0x08 +#define RDL2_RDL22 0x04 +#define RDL2_RDL21 0x02 +#define RDL2_RDL20 0x01 + +#define RDL3_RDL37 0x80 +#define RDL3_RDL36 0x40 +#define RDL3_RDL35 0x20 +#define RDL3_RDL34 0x10 +#define RDL3_RDL33 0x08 +#define RDL3_RDL32 0x04 +#define RDL3_RDL31 0x02 +#define RDL3_RDL30 0x01 + + +/* SIS (Signaling Status Register) + + -------------------- E1 & T1 -------------------------- */ + +#define SIS_XDOV 0x80 +#define SIS_XFW 0x40 +#define SIS_XREP 0x20 +#define SIS_RLI 0x08 +#define SIS_CEC 0x04 +#define SIS_BOM 0x01 + + +/* RSIS (Receive Signaling Status Register) + + -------------------- E1 & T1 --------------------------- */ + +#define RSIS_VFR 0x80 +#define RSIS_RDO 0x40 +#define RSIS_CRC16 0x20 +#define RSIS_RAB 0x10 +#define RSIS_HA1 0x08 +#define RSIS_HA0 0x04 +#define RSIS_HFR 0x02 +#define RSIS_LA 0x01 + + +/* RBCL/H (Receive Byte Count Low/High) + + ------------------- E1 & T1 ----------------------- */ + +#define RBCL_RBC7 0x80 +#define RBCL_RBC6 0x40 +#define RBCL_RBC5 0x20 +#define RBCL_RBC4 0x10 +#define RBCL_RBC3 0x08 +#define RBCL_RBC2 0x04 +#define RBCL_RBC1 0x02 +#define RBCL_RBC0 0x01 + +#define RBCH_OV 0x10 +#define RBCH_RBC11 0x08 +#define RBCH_RBC10 0x04 +#define RBCH_RBC9 0x02 +#define RBCH_RBC8 0x01 + + +/* ISR1-3 (Interrupt Status Register 1-3) + + ------------------ E1 & T1 ------------------------------ */ + +#define FISR0_RME 0x80 +#define FISR0_RFS 0x40 +#define FISR0_T8MS 0x20 +#define FISR0_ISF 0x20 +#define FISR0_RMB 0x10 +#define FISR0_CASC 0x08 +#define FISR0_RSC 0x08 +#define FISR0_CRC6 0x04 +#define FISR0_CRC4 0x04 +#define FISR0_PDEN 0x02 +#define FISR0_RPF 0x01 + +#define FISR1_CASE 0x80 +#define FISR1_LLBSC 0x80 +#define FISR1_RDO 0x40 +#define FISR1_ALLS 0x20 +#define FISR1_XDU 0x10 +#define FISR1_XMB 0x08 +#define FISR1_XLSC 0x02 +#define FISR1_XPR 0x01 + +#define FISR2_FAR 0x80 +#define FISR2_LFA 0x40 +#define FISR2_MFAR 0x20 +#define FISR2_T400MS 0x10 +#define FISR2_LMFA 0x10 +#define FISR2_AIS 0x08 +#define FISR2_LOS 0x04 +#define FISR2_RAR 0x02 +#define FISR2_RA 0x01 + +#define FISR3_ES 0x80 +#define FISR3_SEC 0x40 +#define FISR3_LMFA16 0x20 +#define FISR3_AIS16 0x10 +#define FISR3_RA16 0x08 +#define FISR3_API 0x04 +#define FISR3_XSLP 0x20 +#define FISR3_XSLN 0x10 +#define FISR3_LLBSC 0x08 +#define FISR3_XRS 0x04 +#define FISR3_SLN 0x02 +#define FISR3_SLP 0x01 + + +/* GIS (Global Interrupt Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define GIS_ISR3 0x08 +#define GIS_ISR2 0x04 +#define GIS_ISR1 0x02 +#define GIS_ISR0 0x01 + + +/* VSTR (Version Status Register) + + --------------------- E1 & T1 --------------------- */ + +#define VSTR_VN3 0x08 +#define VSTR_VN2 0x04 +#define VSTR_VN1 0x02 +#define VSTR_VN0 0x01 + + +/*>>>>>>>>>>>>>>>>>>>>> Local Control Structures <<<<<<<<<<<<<<<<<<<<<<<<< */ + +/* Write-only Registers (E1/T1 control mode write registers) */ +#define XFIFOH 0x00 /* Tx FIFO High Byte */ +#define XFIFOL 0x01 /* Tx FIFO Low Byte */ +#define CMDR 0x02 /* Command Reg */ +#define DEC 0x60 /* Disable Error Counter */ +#define TEST2 0x62 /* Manuf. Test Reg 2 */ +#define XS(nbr) (0x70 + (nbr)) /* Tx CAS Reg (0 to 15) */ + +/* Read-write Registers (E1/T1 status mode read registers) */ +#define MODE 0x03 /* Mode Reg */ +#define RAH1 0x04 /* Receive Address High 1 */ +#define RAH2 0x05 /* Receive Address High 2 */ +#define RAL1 0x06 /* Receive Address Low 1 */ +#define RAL2 0x07 /* Receive Address Low 2 */ +#define IPC 0x08 /* Interrupt Port Configuration */ +#define CCR1 0x09 /* Common Configuration Reg 1 */ +#define CCR3 0x0A /* Common Configuration Reg 3 */ +#define PRE 0x0B /* Preamble Reg */ +#define RTR1 0x0C /* Receive Timeslot Reg 1 */ +#define RTR2 0x0D /* Receive Timeslot Reg 2 */ +#define RTR3 0x0E /* Receive Timeslot Reg 3 */ +#define RTR4 0x0F /* Receive Timeslot Reg 4 */ +#define TTR1 0x10 /* Transmit Timeslot Reg 1 */ +#define TTR2 0x11 /* Transmit Timeslot Reg 2 */ +#define TTR3 0x12 /* Transmit Timeslot Reg 3 */ +#define TTR4 0x13 /* Transmit Timeslot Reg 4 */ +#define IMR0 0x14 /* Interrupt Mask Reg 0 */ +#define IMR1 0x15 /* Interrupt Mask Reg 1 */ +#define IMR2 0x16 /* Interrupt Mask Reg 2 */ +#define IMR3 0x17 /* Interrupt Mask Reg 3 */ +#define IMR4 0x18 /* Interrupt Mask Reg 4 */ +#define IMR5 0x19 /* Interrupt Mask Reg 5 */ +#define FMR0 0x1A /* Framer Mode Reigster 0 */ +#define FMR1 0x1B /* Framer Mode Reigster 1 */ +#define FMR2 0x1C /* Framer Mode Reigster 2 */ +#define LOOP 0x1D /* Channel Loop Back */ +#define XSW 0x1E /* Transmit Service Word */ +#define FMR4 0x1E /* Framer Mode Reg 4 */ +#define XSP 0x1F /* Transmit Spare Bits */ +#define FMR5 0x1F /* Framer Mode Reg 5 */ +#define XC0 0x20 /* Transmit Control 0 */ +#define XC1 0x21 /* Transmit Control 1 */ +#define RC0 0x22 /* Receive Control 0 */ +#define RC1 0x23 /* Receive Control 1 */ +#define XPM0 0x24 /* Transmit Pulse Mask 0 */ +#define XPM1 0x25 /* Transmit Pulse Mask 1 */ +#define XPM2 0x26 /* Transmit Pulse Mask 2 */ +#define TSWM 0x27 /* Transparent Service Word Mask */ +#define TEST1 0x28 /* Manuf. Test Reg 1 */ +#define IDLE 0x29 /* Idle Channel Code */ +#define XSA4 0x2A /* Transmit SA4 Bit Reg */ +#define XDL1 0x2A /* Transmit DL-Bit Reg 2 */ +#define XSA5 0x2B /* Transmit SA4 Bit Reg */ +#define XDL2 0x2B /* Transmit DL-Bit Reg 2 */ +#define XSA6 0x2C /* Transmit SA4 Bit Reg */ +#define XDL3 0x2C /* Transmit DL-Bit Reg 2 */ +#define XSA7 0x2D /* Transmit SA4 Bit Reg */ +#define CCB1 0x2D /* Clear Channel Reg 1 */ +#define XSA8 0x2E /* Transmit SA4 Bit Reg */ +#define CCB2 0x2E /* Clear Channel Reg 2 */ +#define FMR3 0x2F /* Framer Mode Reg. 3 */ +#define CCB3 0x2F /* Clear Channel Reg 3 */ +#define ICB1 0x30 /* Idle Channel Reg 1 */ +#define ICB2 0x31 /* Idle Channel Reg 2 */ +#define ICB3 0x32 /* Idle Channel Reg 3 */ +#define ICB4 0x33 /* Idle Channel Reg 4 */ +#define LIM0 0x34 /* Line Interface Mode 0 */ +#define LIM1 0x35 /* Line Interface Mode 1 */ +#define PCDR 0x36 /* Pulse Count Detection */ +#define PCRR 0x37 /* Pulse Count Recovery */ +#define LIM2 0x38 /* Line Interface Mode Reg 2 */ +#define LCR1 0x39 /* Loop Code Reg 1 */ +#define LCR2 0x3A /* Loop Code Reg 2 */ +#define LCR3 0x3B /* Loop Code Reg 3 */ +#define SIC1 0x3C /* System Interface Control 1 */ + +/* Read-only Registers (E1/T1 control mode read registers) */ +#define RFIFOH 0x00 /* Receive FIFO */ +#define RFIFOL 0x01 /* Receive FIFO */ +#define FRS0 0x4C /* Framer Receive Status 0 */ +#define FRS1 0x4D /* Framer Receive Status 1 */ +#define RSW 0x4E /* Receive Service Word */ +#define FRS2 0x4E /* Framer Receive Status 2 */ +#define RSP 0x4F /* Receive Spare Bits */ +#define FRS3 0x4F /* Framer Receive Status 3 */ +#define FECL 0x50 /* Framing Error Counter */ +#define FECH 0x51 /* Framing Error Counter */ +#define CVCL 0x52 /* Code Violation Counter */ +#define CVCH 0x53 /* Code Violation Counter */ +#define CECL 0x54 /* CRC Error Counter 1 */ +#define CECH 0x55 /* CRC Error Counter 1 */ +#define EBCL 0x56 /* E-Bit Error Counter */ +#define EBCH 0x57 /* E-Bit Error Counter */ +#define BECL 0x58 /* Bit Error Counter Low */ +#define BECH 0x59 /* Bit Error Counter Low */ +#define CEC3 0x5A /* CRC Error Counter 3 (16-bit) */ +#define RSA4 0x5C /* Receive SA4 Bit Reg */ +#define RDL1 0x5C /* Receive DL-Bit Reg 1 */ +#define RSA5 0x5D /* Receive SA5 Bit Reg */ +#define RDL2 0x5D /* Receive DL-Bit Reg 2 */ +#define RSA6 0x5E /* Receive SA6 Bit Reg */ +#define RDL3 0x5E /* Receive DL-Bit Reg 3 */ +#define RSA7 0x5F /* Receive SA7 Bit Reg */ +#define RSA8 0x60 /* Receive SA8 Bit Reg */ +#define RSA6S 0x61 /* Receive SA6 Bit Status Reg */ +#define TSR0 0x62 /* Manuf. Test Reg 0 */ +#define TSR1 0x63 /* Manuf. Test Reg 1 */ +#define SIS 0x64 /* Signaling Status Reg */ +#define RSIS 0x65 /* Receive Signaling Status Reg */ +#define RBCL 0x66 /* Receive Byte Control */ +#define RBCH 0x67 /* Receive Byte Control */ +#define FISR0 0x68 /* Interrupt Status Reg 0 */ +#define FISR1 0x69 /* Interrupt Status Reg 1 */ +#define FISR2 0x6A /* Interrupt Status Reg 2 */ +#define FISR3 0x6B /* Interrupt Status Reg 3 */ +#define GIS 0x6E /* Global Interrupt Status */ +#define VSTR 0x6F /* Version Status */ +#define RS(nbr) (0x70 + (nbr)) /* Rx CAS Reg (0 to 15) */ + +#endif /* _FALC_LH_H */ + diff --git a/drivers/staging/net/pc300.h b/drivers/staging/net/pc300.h new file mode 100644 index 0000000..2e4f84f --- /dev/null +++ b/drivers/staging/net/pc300.h @@ -0,0 +1,436 @@ +/* + * pc300.h Cyclades-PC300(tm) Kernel API Definitions. + * + * Author: Ivan Passos <ivan@cyclades.com> + * + * Copyright: (c) 1999-2002 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * $Log: pc300.h,v $ + * Revision 3.12 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.11 2002/01/28 21:09:39 daniela + * Included ';' after pc300hw.bus. + * + * Revision 3.10 2002/01/17 17:58:52 ivan + * Support for PC300-TE/M (PMC). + * + * Revision 3.9 2001/09/28 13:30:53 daniela + * Renamed dma_start routine to rx_dma_start. + * + * Revision 3.8 2001/09/24 13:03:45 daniela + * Fixed BOF interrupt treatment. Created dma_start routine. + * + * Revision 3.7 2001/08/10 17:19:58 daniela + * Fixed IOCTLs defines. + * + * Revision 3.6 2001/07/18 19:24:42 daniela + * Included kernel version. + * + * Revision 3.5 2001/07/05 18:38:08 daniela + * DMA transmission bug fix. + * + * Revision 3.4 2001/06/26 17:10:40 daniela + * New configuration parameters (line code, CRC calculation and clock). + * + * Revision 3.3 2001/06/22 13:13:02 regina + * MLPPP implementation + * + * Revision 3.2 2001/06/18 17:56:09 daniela + * Increased DEF_MTU and TX_QUEUE_LEN. + * + * Revision 3.1 2001/06/15 12:41:10 regina + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:25:06 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 2.3 2001/03/05 daniela + * Created struct pc300conf, to provide the hardware information to pc300util. + * Inclusion of 'alloc_ramsize' field on structure 'pc300hw'. + * + * Revision 2.2 2000/12/22 daniela + * Structures and defines to support pc300util: statistics, status, + * loopback tests, trace. + * + * Revision 2.1 2000/09/28 ivan + * Inclusion of 'iophys' and 'iosize' fields on structure 'pc300hw', to + * allow release of I/O region at module unload. + * Changed location of include files. + * + * Revision 2.0 2000/03/27 ivan + * Added support for the PC300/TE cards. + * + * Revision 1.1 2000/01/31 ivan + * Replaced 'pc300[drv|sca].h' former PC300 driver include files. + * + * Revision 1.0 1999/12/16 ivan + * First official release. + * Inclusion of 'nchan' field on structure 'pc300hw', to allow variable + * number of ports per card. + * Inclusion of 'if_ptr' field on structure 'pc300dev'. + * + * Revision 0.6 1999/11/17 ivan + * Changed X.25-specific function names to comply with adopted convention. + * + * Revision 0.5 1999/11/16 Daniela Squassoni + * X.25 support. + * + * Revision 0.4 1999/11/15 ivan + * Inclusion of 'clock' field on structure 'pc300hw'. + * + * Revision 0.3 1999/11/10 ivan + * IOCTL name changing. + * Inclusion of driver function prototypes. + * + * Revision 0.2 1999/11/03 ivan + * Inclusion of 'tx_skb' and union 'ifu' on structure 'pc300dev'. + * + * Revision 0.1 1999/01/15 ivan + * Initial version. + * + */ + +#ifndef _PC300_H +#define _PC300_H + +#include <linux/hdlc.h> +#include "hd64572.h" +#include "pc300-falc-lh.h" + +#define PC300_PROTO_MLPPP 1 + +#define PC300_MAXCHAN 2 /* Number of channels per card */ + +#define PC300_RAMSIZE 0x40000 /* RAM window size (256Kb) */ +#define PC300_FALCSIZE 0x400 /* FALC window size (1Kb) */ + +#define PC300_OSC_CLOCK 24576000 +#define PC300_PCI_CLOCK 33000000 + +#define BD_DEF_LEN 0x0800 /* DMA buffer length (2KB) */ +#define DMA_TX_MEMSZ 0x8000 /* Total DMA Tx memory size (32KB/ch) */ +#define DMA_RX_MEMSZ 0x10000 /* Total DMA Rx memory size (64KB/ch) */ + +#define N_DMA_TX_BUF (DMA_TX_MEMSZ / BD_DEF_LEN) /* DMA Tx buffers */ +#define N_DMA_RX_BUF (DMA_RX_MEMSZ / BD_DEF_LEN) /* DMA Rx buffers */ + +/* DMA Buffer Offsets */ +#define DMA_TX_BASE ((N_DMA_TX_BUF + N_DMA_RX_BUF) * \ + PC300_MAXCHAN * sizeof(pcsca_bd_t)) +#define DMA_RX_BASE (DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ) + +/* DMA Descriptor Offsets */ +#define DMA_TX_BD_BASE 0x0000 +#define DMA_RX_BD_BASE (DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \ + BD_DEF_LEN) * sizeof(pcsca_bd_t))) + +/* DMA Descriptor Macros */ +#define TX_BD_ADDR(chan, n) (DMA_TX_BD_BASE + \ + ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t)) +#define RX_BD_ADDR(chan, n) (DMA_RX_BD_BASE + \ + ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t)) + +/* Macro to access the FALC registers (TE only) */ +#define F_REG(reg, chan) (0x200*(chan) + ((reg)<<2)) + +/*************************************** + * Memory access functions/macros * + * (required to support Alpha systems) * + ***************************************/ +#define cpc_writeb(port,val) {writeb((u8)(val),(port)); mb();} +#define cpc_writew(port,val) {writew((ushort)(val),(port)); mb();} +#define cpc_writel(port,val) {writel((u32)(val),(port)); mb();} + +#define cpc_readb(port) readb(port) +#define cpc_readw(port) readw(port) +#define cpc_readl(port) readl(port) + +/****** Data Structures *****************************************************/ + +/* + * RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime + * registers. This structure can be used to access the 9050 registers + * (memory mapped). + */ +struct RUNTIME_9050 { + u32 loc_addr_range[4]; /* 00-0Ch : Local Address Ranges */ + u32 loc_rom_range; /* 10h : Local ROM Range */ + u32 loc_addr_base[4]; /* 14-20h : Local Address Base Addrs */ + u32 loc_rom_base; /* 24h : Local ROM Base */ + u32 loc_bus_descr[4]; /* 28-34h : Local Bus Descriptors */ + u32 rom_bus_descr; /* 38h : ROM Bus Descriptor */ + u32 cs_base[4]; /* 3C-48h : Chip Select Base Addrs */ + u32 intr_ctrl_stat; /* 4Ch : Interrupt Control/Status */ + u32 init_ctrl; /* 50h : EEPROM ctrl, Init Ctrl, etc */ +}; + +#define PLX_9050_LINT1_ENABLE 0x01 +#define PLX_9050_LINT1_POL 0x02 +#define PLX_9050_LINT1_STATUS 0x04 +#define PLX_9050_LINT2_ENABLE 0x08 +#define PLX_9050_LINT2_POL 0x10 +#define PLX_9050_LINT2_STATUS 0x20 +#define PLX_9050_INTR_ENABLE 0x40 +#define PLX_9050_SW_INTR 0x80 + +/* Masks to access the init_ctrl PLX register */ +#define PC300_CLKSEL_MASK (0x00000004UL) +#define PC300_CHMEDIA_MASK(chan) (0x00000020UL<<(chan*3)) +#define PC300_CTYPE_MASK (0x00000800UL) + +/* CPLD Registers (base addr = falcbase, TE only) */ +/* CPLD v. 0 */ +#define CPLD_REG1 0x140 /* Chip resets, DCD/CTS status */ +#define CPLD_REG2 0x144 /* Clock enable , LED control */ +/* CPLD v. 2 or higher */ +#define CPLD_V2_REG1 0x100 /* Chip resets, DCD/CTS status */ +#define CPLD_V2_REG2 0x104 /* Clock enable , LED control */ +#define CPLD_ID_REG 0x108 /* CPLD version */ + +/* CPLD Register bit description: for the FALC bits, they should always be + set based on the channel (use (bit<<(2*ch)) to access the correct bit for + that channel) */ +#define CPLD_REG1_FALC_RESET 0x01 +#define CPLD_REG1_SCA_RESET 0x02 +#define CPLD_REG1_GLOBAL_CLK 0x08 +#define CPLD_REG1_FALC_DCD 0x10 +#define CPLD_REG1_FALC_CTS 0x20 + +#define CPLD_REG2_FALC_TX_CLK 0x01 +#define CPLD_REG2_FALC_RX_CLK 0x02 +#define CPLD_REG2_FALC_LED1 0x10 +#define CPLD_REG2_FALC_LED2 0x20 + +/* Structure with FALC-related fields (TE only) */ +#define PC300_FALC_MAXLOOP 0x0000ffff /* for falc_issue_cmd() */ + +typedef struct falc { + u8 sync; /* If true FALC is synchronized */ + u8 active; /* if TRUE then already active */ + u8 loop_active; /* if TRUE a line loopback UP was received */ + u8 loop_gen; /* if TRUE a line loopback UP was issued */ + + u8 num_channels; + u8 offset; /* 1 for T1, 0 for E1 */ + u8 full_bandwidth; + + u8 xmb_cause; + u8 multiframe_mode; + + /* Statistics */ + u16 pden; /* Pulse Density violation count */ + u16 los; /* Loss of Signal count */ + u16 losr; /* Loss of Signal recovery count */ + u16 lfa; /* Loss of frame alignment count */ + u16 farec; /* Frame Alignment Recovery count */ + u16 lmfa; /* Loss of multiframe alignment count */ + u16 ais; /* Remote Alarm indication Signal count */ + u16 sec; /* One-second timer */ + u16 es; /* Errored second */ + u16 rai; /* remote alarm received */ + u16 bec; + u16 fec; + u16 cvc; + u16 cec; + u16 ebc; + + /* Status */ + u8 red_alarm; + u8 blue_alarm; + u8 loss_fa; + u8 yellow_alarm; + u8 loss_mfa; + u8 prbs; +} falc_t; + +typedef struct falc_status { + u8 sync; /* If true FALC is synchronized */ + u8 red_alarm; + u8 blue_alarm; + u8 loss_fa; + u8 yellow_alarm; + u8 loss_mfa; + u8 prbs; +} falc_status_t; + +typedef struct rsv_x21_status { + u8 dcd; + u8 dsr; + u8 cts; + u8 rts; + u8 dtr; +} rsv_x21_status_t; + +typedef struct pc300stats { + int hw_type; + u32 line_on; + u32 line_off; + struct net_device_stats gen_stats; + falc_t te_stats; +} pc300stats_t; + +typedef struct pc300status { + int hw_type; + rsv_x21_status_t gen_status; + falc_status_t te_status; +} pc300status_t; + +typedef struct pc300loopback { + char loop_type; + char loop_on; +} pc300loopback_t; + +typedef struct pc300patterntst { + char patrntst_on; /* 0 - off; 1 - on; 2 - read num_errors */ + u16 num_errors; +} pc300patterntst_t; + +typedef struct pc300dev { + struct pc300ch *chan; + u8 trace_on; + u32 line_on; /* DCD(X.21, RSV) / sync(TE) change counters */ + u32 line_off; + char name[16]; + struct net_device *dev; +#ifdef CONFIG_PC300_MLPPP + void *cpc_tty; /* information to PC300 TTY driver */ +#endif +}pc300dev_t; + +typedef struct pc300hw { + int type; /* RSV, X21, etc. */ + int bus; /* Bus (PCI, PMC, etc.) */ + int nchan; /* number of channels */ + int irq; /* interrupt request level */ + u32 clock; /* Board clock */ + u8 cpld_id; /* CPLD ID (TE only) */ + u16 cpld_reg1; /* CPLD reg 1 (TE only) */ + u16 cpld_reg2; /* CPLD reg 2 (TE only) */ + u16 gpioc_reg; /* PLX GPIOC reg */ + u16 intctl_reg; /* PLX Int Ctrl/Status reg */ + u32 iophys; /* PLX registers I/O base */ + u32 iosize; /* PLX registers I/O size */ + u32 plxphys; /* PLX registers MMIO base (physical) */ + void __iomem * plxbase; /* PLX registers MMIO base (virtual) */ + u32 plxsize; /* PLX registers MMIO size */ + u32 scaphys; /* SCA registers MMIO base (physical) */ + void __iomem * scabase; /* SCA registers MMIO base (virtual) */ + u32 scasize; /* SCA registers MMIO size */ + u32 ramphys; /* On-board RAM MMIO base (physical) */ + void __iomem * rambase; /* On-board RAM MMIO base (virtual) */ + u32 alloc_ramsize; /* RAM MMIO size allocated by the PCI bridge */ + u32 ramsize; /* On-board RAM MMIO size */ + u32 falcphys; /* FALC registers MMIO base (physical) */ + void __iomem * falcbase;/* FALC registers MMIO base (virtual) */ + u32 falcsize; /* FALC registers MMIO size */ +} pc300hw_t; + +typedef struct pc300chconf { + sync_serial_settings phys_settings; /* Clock type/rate (in bps), + loopback mode */ + raw_hdlc_proto proto_settings; /* Encoding, parity (CRC) */ + u32 media; /* HW media (RS232, V.35, etc.) */ + u32 proto; /* Protocol (PPP, X.25, etc.) */ + + /* TE-specific parameters */ + u8 lcode; /* Line Code (AMI, B8ZS, etc.) */ + u8 fr_mode; /* Frame Mode (ESF, D4, etc.) */ + u8 lbo; /* Line Build Out */ + u8 rx_sens; /* Rx Sensitivity (long- or short-haul) */ + u32 tslot_bitmap; /* bit[i]=1 => timeslot _i_ is active */ +} pc300chconf_t; + +typedef struct pc300ch { + struct pc300 *card; + int channel; + pc300dev_t d; + pc300chconf_t conf; + u8 tx_first_bd; /* First TX DMA block descr. w/ data */ + u8 tx_next_bd; /* Next free TX DMA block descriptor */ + u8 rx_first_bd; /* First free RX DMA block descriptor */ + u8 rx_last_bd; /* Last free RX DMA block descriptor */ + u8 nfree_tx_bd; /* Number of free TX DMA block descriptors */ + falc_t falc; /* FALC structure (TE only) */ +} pc300ch_t; + +typedef struct pc300 { + pc300hw_t hw; /* hardware config. */ + pc300ch_t chan[PC300_MAXCHAN]; + spinlock_t card_lock; +} pc300_t; + +typedef struct pc300conf { + pc300hw_t hw; + pc300chconf_t conf; +} pc300conf_t; + +/* DEV ioctl() commands */ +#define N_SPPP_IOCTLS 2 + +enum pc300_ioctl_cmds { + SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS), + SIOCGPC300CONF, + SIOCSPC300CONF, + SIOCGPC300STATUS, + SIOCGPC300FALCSTATUS, + SIOCGPC300UTILSTATS, + SIOCGPC300UTILSTATUS, + SIOCSPC300TRACE, + SIOCSPC300LOOPBACK, + SIOCSPC300PATTERNTEST, +}; + +/* Loopback types - PC300/TE boards */ +enum pc300_loopback_cmds { + PC300LOCLOOP = 1, + PC300REMLOOP, + PC300PAYLOADLOOP, + PC300GENLOOPUP, + PC300GENLOOPDOWN, +}; + +/* Control Constant Definitions */ +#define PC300_RSV 0x01 +#define PC300_X21 0x02 +#define PC300_TE 0x03 + +#define PC300_PCI 0x00 +#define PC300_PMC 0x01 + +#define PC300_LC_AMI 0x01 +#define PC300_LC_B8ZS 0x02 +#define PC300_LC_NRZ 0x03 +#define PC300_LC_HDB3 0x04 + +/* Framing (T1) */ +#define PC300_FR_ESF 0x01 +#define PC300_FR_D4 0x02 +#define PC300_FR_ESF_JAPAN 0x03 + +/* Framing (E1) */ +#define PC300_FR_MF_CRC4 0x04 +#define PC300_FR_MF_NON_CRC4 0x05 +#define PC300_FR_UNFRAMED 0x06 + +#define PC300_LBO_0_DB 0x00 +#define PC300_LBO_7_5_DB 0x01 +#define PC300_LBO_15_DB 0x02 +#define PC300_LBO_22_5_DB 0x03 + +#define PC300_RX_SENS_SH 0x01 +#define PC300_RX_SENS_LH 0x02 + +#define PC300_TX_TIMEOUT (2*HZ) +#define PC300_TX_QUEUE_LEN 100 +#define PC300_DEF_MTU 1600 + +/* Function Prototypes */ +int cpc_open(struct net_device *dev); + +#endif /* _PC300_H */ diff --git a/drivers/staging/net/pc300_drv.c b/drivers/staging/net/pc300_drv.c new file mode 100644 index 0000000..cb0f8d9 --- /dev/null +++ b/drivers/staging/net/pc300_drv.c @@ -0,0 +1,3670 @@ +#define USE_PCI_CLOCK +static const char rcsid[] = +"Revision: 3.4.5 Date: 2002/03/07 "; + +/* + * pc300.c Cyclades-PC300(tm) Driver. + * + * Author: Ivan Passos <ivan@cyclades.com> + * Maintainer: PC300 Maintainer <pc300@cyclades.com> + * + * Copyright: (c) 1999-2003 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Using tabstop = 4. + * + * $Log: pc300_drv.c,v $ + * Revision 3.23 2002/03/20 13:58:40 henrique + * Fixed ortographic mistakes + * + * Revision 3.22 2002/03/13 16:56:56 henrique + * Take out the debug messages + * + * Revision 3.21 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.20 2002/01/17 17:58:52 ivan + * Support for PC300-TE/M (PMC). + * + * Revision 3.19 2002/01/03 17:08:47 daniela + * Enables DMA reception when the SCA-II disables it improperly. + * + * Revision 3.18 2001/12/03 18:47:50 daniela + * Esthetic changes. + * + * Revision 3.17 2001/10/19 16:50:13 henrique + * Patch to kernel 2.4.12 and new generic hdlc. + * + * Revision 3.16 2001/10/16 15:12:31 regina + * clear statistics + * + * Revision 3.11 to 3.15 2001/10/11 20:26:04 daniela + * More DMA fixes for noisy lines. + * Return the size of bad frames in dma_get_rx_frame_size, so that the Rx buffer + * descriptors can be cleaned by dma_buf_read (called in cpc_net_rx). + * Renamed dma_start routine to rx_dma_start. Improved Rx statistics. + * Fixed BOF interrupt treatment. Created dma_start routine. + * Changed min and max to cpc_min and cpc_max. + * + * Revision 3.10 2001/08/06 12:01:51 regina + * Fixed problem in DSR_DE bit. + * + * Revision 3.9 2001/07/18 19:27:26 daniela + * Added some history comments. + * + * Revision 3.8 2001/07/12 13:11:19 regina + * bug fix - DCD-OFF in pc300 tty driver + * + * Revision 3.3 to 3.7 2001/07/06 15:00:20 daniela + * Removing kernel 2.4.3 and previous support. + * DMA transmission bug fix. + * MTU check in cpc_net_rx fixed. + * Boot messages reviewed. + * New configuration parameters (line code, CRC calculation and clock). + * + * Revision 3.2 2001/06/22 13:13:02 regina + * MLPPP implementation. Changed the header of message trace to include + * the device name. New format : "hdlcX[R/T]: ". + * Default configuration changed. + * + * Revision 3.1 2001/06/15 regina + * in cpc_queue_xmit, netif_stop_queue is called if don't have free descriptor + * upping major version number + * + * Revision 1.1.1.1 2001/06/13 20:25:04 daniela + * PC300 initial CVS version (3.4.0-pre1) + * + * Revision 3.0.1.2 2001/06/08 daniela + * Did some changes in the DMA programming implementation to avoid the + * occurrence of a SCA-II bug when CDA is accessed during a DMA transfer. + * + * Revision 3.0.1.1 2001/05/02 daniela + * Added kernel 2.4.3 support. + * + * Revision 3.0.1.0 2001/03/13 daniela, henrique + * Added Frame Relay Support. + * Driver now uses HDLC generic driver to provide protocol support. + * + * Revision 3.0.0.8 2001/03/02 daniela + * Fixed ram size detection. + * Changed SIOCGPC300CONF ioctl, to give hw information to pc300util. + * + * Revision 3.0.0.7 2001/02/23 daniela + * netif_stop_queue called before the SCA-II transmition commands in + * cpc_queue_xmit, and with interrupts disabled to avoid race conditions with + * transmition interrupts. + * Fixed falc_check_status for Unframed E1. + * + * Revision 3.0.0.6 2000/12/13 daniela + * Implemented pc300util support: trace, statistics, status and loopback + * tests for the PC300 TE boards. + * + * Revision 3.0.0.5 2000/12/12 ivan + * Added support for Unframed E1. + * Implemented monitor mode. + * Fixed DCD sensitivity on the second channel. + * Driver now complies with new PCI kernel architecture. + * + * Revision 3.0.0.4 2000/09/28 ivan + * Implemented DCD sensitivity. + * Moved hardware-specific open to the end of cpc_open, to avoid race + * conditions with early reception interrupts. + * Included code for [request|release]_mem_region(). + * Changed location of pc300.h . + * Minor code revision (contrib. of Jeff Garzik). + * + * Revision 3.0.0.3 2000/07/03 ivan + * Previous bugfix for the framing errors with external clock made X21 + * boards stop working. This version fixes it. + * + * Revision 3.0.0.2 2000/06/23 ivan + * Revisited cpc_queue_xmit to prevent race conditions on Tx DMA buffer + * handling when Tx timeouts occur. + * Revisited Rx statistics. + * Fixed a bug in the SCA-II programming that would cause framing errors + * when external clock was configured. + * + * Revision 3.0.0.1 2000/05/26 ivan + * Added logic in the SCA interrupt handler so that no board can monopolize + * the driver. + * Request PLX I/O region, although driver doesn't use it, to avoid + * problems with other drivers accessing it. + * + * Revision 3.0.0.0 2000/05/15 ivan + * Did some changes in the DMA programming implementation to avoid the + * occurrence of a SCA-II bug in the second channel. + * Implemented workaround for PLX9050 bug that would cause a system lockup + * in certain systems, depending on the MMIO addresses allocated to the + * board. + * Fixed the FALC chip programming to avoid synchronization problems in the + * second channel (TE only). + * Implemented a cleaner and faster Tx DMA descriptor cleanup procedure in + * cpc_queue_xmit(). + * Changed the built-in driver implementation so that the driver can use the + * general 'hdlcN' naming convention instead of proprietary device names. + * Driver load messages are now device-centric, instead of board-centric. + * Dynamic allocation of net_device structures. + * Code is now compliant with the new module interface (module_[init|exit]). + * Make use of the PCI helper functions to access PCI resources. + * + * Revision 2.0.0.0 2000/04/15 ivan + * Added support for the PC300/TE boards (T1/FT1/E1/FE1). + * + * Revision 1.1.0.0 2000/02/28 ivan + * Major changes in the driver architecture. + * Softnet compliancy implemented. + * Driver now reports physical instead of virtual memory addresses. + * Added cpc_change_mtu function. + * + * Revision 1.0.0.0 1999/12/16 ivan + * First official release. + * Support for 1- and 2-channel boards (which use distinct PCI Device ID's). + * Support for monolythic installation (i.e., drv built into the kernel). + * X.25 additional checking when lapb_[dis]connect_request returns an error. + * SCA programming now covers X.21 as well. + * + * Revision 0.3.1.0 1999/11/18 ivan + * Made X.25 support configuration-dependent (as it depends on external + * modules to work). + * Changed X.25-specific function names to comply with adopted convention. + * Fixed typos in X.25 functions that would cause compile errors (Daniela). + * Fixed bug in ch_config that would disable interrupts on a previously + * enabled channel if the other channel on the same board was enabled later. + * + * Revision 0.3.0.0 1999/11/16 daniela + * X.25 support. + * + * Revision 0.2.3.0 1999/11/15 ivan + * Function cpc_ch_status now provides more detailed information. + * Added support for X.21 clock configuration. + * Changed TNR1 setting in order to prevent Tx FIFO overaccesses by the SCA. + * Now using PCI clock instead of internal oscillator clock for the SCA. + * + * Revision 0.2.2.0 1999/11/10 ivan + * Changed the *_dma_buf_check functions so that they would print only + * the useful info instead of the whole buffer descriptor bank. + * Fixed bug in cpc_queue_xmit that would eventually crash the system + * in case of a packet drop. + * Implemented TX underrun handling. + * Improved SCA fine tuning to boost up its performance. + * + * Revision 0.2.1.0 1999/11/03 ivan + * Added functions *dma_buf_pt_init to allow independent initialization + * of the next-descr. and DMA buffer pointers on the DMA descriptors. + * Kernel buffer release and tbusy clearing is now done in the interrupt + * handler. + * Fixed bug in cpc_open that would cause an interface reopen to fail. + * Added a protocol-specific code section in cpc_net_rx. + * Removed printk level defs (they might be added back after the beta phase). + * + * Revision 0.2.0.0 1999/10/28 ivan + * Revisited the code so that new protocols can be easily added / supported. + * + * Revision 0.1.0.1 1999/10/20 ivan + * Mostly "esthetic" changes. + * + * Revision 0.1.0.0 1999/10/11 ivan + * Initial version. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/ioport.h> +#include <linux/pci.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/net.h> +#include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/spinlock.h> +#include <linux/if.h> +#include <linux/slab.h> +#include <net/arp.h> + +#include <asm/io.h> +#include <asm/uaccess.h> + +#include "pc300.h" + +#define CPC_LOCK(card,flags) \ + do { \ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_UNLOCK(card,flags) \ + do { \ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +#undef PC300_DEBUG_PCI +#undef PC300_DEBUG_INTR +#undef PC300_DEBUG_TX +#undef PC300_DEBUG_RX +#undef PC300_DEBUG_OTHER + +static DEFINE_PCI_DEVICE_TABLE(cpc_pci_dev_id) = { + /* PC300/RSV or PC300/X21, 2 chan */ + {0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300}, + /* PC300/RSV or PC300/X21, 1 chan */ + {0x120e, 0x301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x301}, + /* PC300/TE, 2 chan */ + {0x120e, 0x310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x310}, + /* PC300/TE, 1 chan */ + {0x120e, 0x311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x311}, + /* PC300/TE-M, 2 chan */ + {0x120e, 0x320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x320}, + /* PC300/TE-M, 1 chan */ + {0x120e, 0x321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x321}, + /* End of table */ + {0,}, +}; +MODULE_DEVICE_TABLE(pci, cpc_pci_dev_id); + +#ifndef cpc_min +#define cpc_min(a,b) (((a)<(b))?(a):(b)) +#endif +#ifndef cpc_max +#define cpc_max(a,b) (((a)>(b))?(a):(b)) +#endif + +/* prototypes */ +static void tx_dma_buf_pt_init(pc300_t *, int); +static void tx_dma_buf_init(pc300_t *, int); +static void rx_dma_buf_pt_init(pc300_t *, int); +static void rx_dma_buf_init(pc300_t *, int); +static void tx_dma_buf_check(pc300_t *, int); +static void rx_dma_buf_check(pc300_t *, int); +static irqreturn_t cpc_intr(int, void *); +static int clock_rate_calc(u32, u32, int *); +static u32 detect_ram(pc300_t *); +static void plx_init(pc300_t *); +static void cpc_trace(struct net_device *, struct sk_buff *, char); +static int cpc_attach(struct net_device *, unsigned short, unsigned short); +static int cpc_close(struct net_device *dev); + +#ifdef CONFIG_PC300_MLPPP +void cpc_tty_init(pc300dev_t * dev); +void cpc_tty_unregister_service(pc300dev_t * pc300dev); +void cpc_tty_receive(pc300dev_t * pc300dev); +void cpc_tty_trigger_poll(pc300dev_t * pc300dev); +#endif + +/************************/ +/*** DMA Routines ***/ +/************************/ +static void tx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (u32)(DMA_TX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (u32)(DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void tx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_TX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, DST_OSB); + } + tx_dma_buf_pt_init(card, ch); +} + +static void rx_dma_buf_pt_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + cpc_writel(&ptdescr->next, (u32)(DMA_RX_BD_BASE + + (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t))); + cpc_writel(&ptdescr->ptbuf, + (u32)(DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN)); + } +} + +static void rx_dma_buf_init(pc300_t * card, int ch) +{ + int i; + int ch_factor = ch * N_DMA_RX_BUF; + volatile pcsca_bd_t __iomem *ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + + for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) { + memset_io(ptdescr, 0, sizeof(pcsca_bd_t)); + cpc_writew(&ptdescr->len, 0); + cpc_writeb(&ptdescr->status, 0); + } + rx_dma_buf_pt_init(card, ch); +} + +static void tx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].tx_first_bd; + u16 next_bd = card->chan[ch].tx_next_bd; + + printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + for (i = first_bd, + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, first_bd)); + i != ((next_bd + 1) & (N_DMA_TX_BUF - 1)); + i = (i + 1) & (N_DMA_TX_BUF - 1), + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i))) { + printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +#ifdef PC300_DEBUG_OTHER +/* Show all TX buffer descriptors */ +static void tx1_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].tx_first_bd; + u16 next_bd = card->chan[ch].tx_next_bd; + u32 scabase = card->hw.scabase; + + printk ("\nnfree_tx_bd = %d\n", card->chan[ch].nfree_tx_bd); + printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, + first_bd, TX_BD_ADDR(ch, first_bd), + next_bd, TX_BD_ADDR(ch, next_bd)); + printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", + cpc_readl(scabase + DTX_REG(CDAL, ch)), + cpc_readl(scabase + DTX_REG(EDAL, ch))); + for (i = 0; i < N_DMA_TX_BUF; i++) { + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch, i)); + printk("\n CH%d TX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len)); + } + printk("\n"); +} +#endif + +static void rx_dma_buf_check(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + int i; + u16 first_bd = card->chan[ch].rx_first_bd; + u16 last_bd = card->chan[ch].rx_last_bd; + int ch_factor; + + ch_factor = ch * N_DMA_RX_BUF; + printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd); + for (i = 0, ptdescr = (card->hw.rambase + + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t)); + i < N_DMA_RX_BUF; i++, ptdescr++) { + if (cpc_readb(&ptdescr->status) & DST_OSB) + printk ("\n CH%d RX%d: next=0x%x, ptbuf=0x%x, ST=0x%x, len=%d", + ch, i, cpc_readl(&ptdescr->next), + cpc_readl(&ptdescr->ptbuf), + cpc_readb(&ptdescr->status), + cpc_readw(&ptdescr->len)); + } + printk("\n"); +} + +static int dma_get_rx_frame_size(pc300_t * card, int ch) +{ + volatile pcsca_bd_t __iomem *ptdescr; + u16 first_bd = card->chan[ch].rx_first_bd; + int rcvd = 0; + volatile u8 status; + + ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rcvd += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { + /* Return the size of a good frame or incomplete bad frame + * (dma_buf_read will clean the buffer descriptors in this case). */ + return rcvd; + } + ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); + } + return -1; +} + +/* + * dma_buf_write: writes a frame to the Tx DMA buffers + * NOTE: this function writes one frame at a time. + */ +static int dma_buf_write(pc300_t *card, int ch, u8 *ptdata, int len) +{ + int i, nchar; + volatile pcsca_bd_t __iomem *ptdescr; + int tosend = len; + u8 nbuf = ((len - 1) / BD_DEF_LEN) + 1; + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return -ENOMEM; + } + + for (i = 0; i < nbuf; i++) { + ptdescr = (card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = cpc_min(BD_DEF_LEN, tosend); + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((card->hw.rambase + cpc_readl(&ptdescr->ptbuf)), + &ptdata[len - tosend], nchar); + cpc_writew(&ptdescr->len, nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + } else { + return -ENOMEM; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + /* If it gets to here, it means we have sent the whole frame */ + return 0; +} + +/* + * dma_buf_read: reads a frame from the Rx DMA buffers + * NOTE: this function reads one frame at a time. + */ +static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) +{ + int nchar; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + volatile pcsca_bd_t __iomem *ptdescr; + int rcvd = 0; + volatile u8 status; + + ptdescr = (card->hw.rambase + + RX_BD_ADDR(ch, chan->rx_first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + nchar = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) || + (nchar > BD_DEF_LEN)) { + + if (nchar > BD_DEF_LEN) + status |= DST_RBIT; + rcvd = -status; + /* Discard remaining descriptors used by the bad frame */ + while (chan->rx_first_bd != chan->rx_last_bd) { + cpc_writeb(&ptdescr->status, 0); + chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1); + if (status & DST_EOM) + break; + ptdescr = (card->hw.rambase + + cpc_readl(&ptdescr->next)); + status = cpc_readb(&ptdescr->status); + } + break; + } + if (nchar != 0) { + if (skb) { + memcpy_fromio(skb_put(skb, nchar), + (card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar); + } + rcvd += nchar; + } + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1); + + if (status & DST_EOM) + break; + + ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); + } + + if (rcvd != 0) { + /* Update pointer */ + chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1); + /* Update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + } + return rcvd; +} + +static void tx_dma_stop(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + u8 drr_ena_bit = 1 << (5 + 2 * ch); + u8 drr_rst_bit = 1 << (1 + 2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +static void rx_dma_stop(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + u8 drr_ena_bit = 1 << (4 + 2 * ch); + u8 drr_rst_bit = 1 << (2 * ch); + + /* Disable DMA */ + cpc_writeb(scabase + DRR, drr_ena_bit); + cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit); +} + +static void rx_dma_start(pc300_t * card, int ch) +{ + void __iomem *scabase = card->hw.scabase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + + /* Start DMA */ + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + if (cpc_readl(scabase + DRX_REG(CDAL,ch)) != + RX_BD_ADDR(ch, chan->rx_first_bd)) { + cpc_writel(scabase + DRX_REG(CDAL, ch), + RX_BD_ADDR(ch, chan->rx_first_bd)); + } + cpc_writel(scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, chan->rx_last_bd)); + cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN); + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + if (!(cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + cpc_writeb(scabase + DSR_RX(ch), DSR_DE); + } +} + +/*************************/ +/*** FALC Routines ***/ +/*************************/ +static void falc_issue_cmd(pc300_t *card, int ch, u8 cmd) +{ + void __iomem *falcbase = card->hw.falcbase; + unsigned long i = 0; + + while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) { + if (i++ >= PC300_FALC_MAXLOOP) { + printk("%s: FALC command locked(cmd=0x%x).\n", + card->chan[ch].d.name, cmd); + break; + } + } + cpc_writeb(falcbase + F_REG(CMDR, ch), cmd); +} + +static void falc_intr_enable(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + /* Interrupt pins are open-drain */ + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0); + /* Conters updated each second */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM); + /* Enable SEC and ES interrupts */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES)); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR4, ch), + cpc_readb(falcbase + F_REG(IMR4, ch)) & + ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP)); + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + cpc_writeb(falcbase + F_REG(IPC, ch), + cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS)); + if (pfalc->multiframe_mode) { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) & + ~(IMR2_T400MS | IMR2_MFAR)); + } else { + cpc_writeb(falcbase + F_REG(IMR2, ch), + cpc_readb(falcbase + F_REG(IMR2, ch)) | + IMR2_T400MS | IMR2_MFAR); + } + } + } +} + +static void falc_open_timeslot(pc300_t * card, int ch, int timeslot) +{ + void __iomem *falcbase = card->hw.falcbase; + u8 tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & + ~(0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | + (0x80 >> (timeslot & 0x07))); +} + +static void falc_close_timeslot(pc300_t * card, int ch, int timeslot) +{ + void __iomem *falcbase = card->hw.falcbase; + u8 tshf = card->chan[ch].falc.offset; + + cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch), + cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | + (0x80 >> ((timeslot - tshf) & 0x07))); + cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); + cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch), + cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & + ~(0x80 >> (timeslot & 0x07))); +} + +static void falc_close_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR1, ch), 0); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0); + cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0); + } +} + +static void falc_open_all_timeslots(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + cpc_writeb(falcbase + F_REG(ICB1, ch), 0); + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff); + } else { + /* Timeslot 0 is never enabled */ + cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f); + cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f); + } + cpc_writeb(falcbase + F_REG(ICB2, ch), 0); + cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff); + cpc_writeb(falcbase + F_REG(ICB3, ch), 0); + cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff); + if (conf->media == IF_IFACE_E1) { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff); + } else { + cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff); + cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80); + cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80); + } +} + +static void falc_init_timeslot(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + int tslot; + + for (tslot = 0; tslot < pfalc->num_channels; tslot++) { + if (conf->tslot_bitmap & (1 << tslot)) { + // Channel enabled + falc_open_timeslot(card, ch, tslot + 1); + } else { + // Channel disabled + falc_close_timeslot(card, ch, tslot + 1); + } + } +} + +static void falc_enable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->full_bandwidth) { + falc_open_all_timeslots(card, ch); + } else { + falc_init_timeslot(card, ch); + } + // CTS/DCD ON + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +static void falc_disable_comm(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + if (pfalc->loop_active != 2) { + falc_close_all_timeslots(card, ch); + } + // CTS/DCD OFF + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch))); +} + +static void falc_init_t1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to T1 mode (PCM 24) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD); + + /* Wait 20 us for setup */ + udelay(20); + + /* Transmit Buffer Size (1 frame) */ + cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); + } + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + /* Clear Channel register to ON for all channels */ + cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff); + cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff); + break; + + case PC300_LC_B8ZS: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00); + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + switch (conf->fr_mode) { + case PC300_FR_ESF: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | + FMR1_CRC | FMR1_EDL); + cpc_writeb(falcbase + F_REG(XDL1, ch), 0); + cpc_writeb(falcbase + F_REG(XDL2, ch), 0); + cpc_writeb(falcbase + F_REG(XDL3, ch), 0); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP); + break; + + case PC300_FR_D4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & + ~(FMR4_FM1 | FMR4_FM0)); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP); + break; + } + + /* Enable Automatic Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Channel translation mode 1 : one to one */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM); + + /* No signaling */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM); + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & + ~(FMR5_EIBR | FMR5_SRS)); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + + switch (conf->lbo) { + /* Provides proper Line Build Out */ + case PC300_LBO_0_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_7_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_15_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + case PC300_LBO_22_5_DB: + cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja)); + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20); + break; + } + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + if (conf->fr_mode == PC300_FR_ESF_JAPAN) { + cpc_writeb(falcbase + F_REG(RC1, ch), + cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80); + } + + falc_close_all_timeslots(card, ch); +} + +static void falc_init_e1(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0); + + /* Switch to E1 mode (PCM 30) */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD); + + /* Clock mode */ + if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); + } else { /* Slave mode */ + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); + } + cpc_writeb(falcbase + F_REG(LOOP, ch), + cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM); + + cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI); + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) & + ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1)); + + switch (conf->lcode) { + case PC300_LC_AMI: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC1 | FMR0_RC1); + break; + + case PC300_LC_HDB3: + cpc_writeb(falcbase + F_REG(FMR0, ch), + cpc_readb(falcbase + F_REG(FMR0, ch)) | + FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1); + break; + + case PC300_LC_NRZ: + break; + } + + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0)); + /* Set interface mode to 2 MBPS */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); + + cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18); + cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03); + cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00); + + switch (conf->fr_mode) { + case PC300_FR_MF_CRC4: + pfalc->multiframe_mode = 1; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0); + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW); + + /* MultiFrame Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS); + + /* Automatic Loss of Multiframe > 914 CRC errors */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF); + + /* S1 and SI1/SI2 spare Bits set to 1 */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XS13 | XSP_XS15); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_MF_NON_CRC4: + case PC300_FR_D4: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF); + + /* Automatic Force Resynchronization */ + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR); + + /* Transmit Automatic Remote Alarm */ + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA); + + /* Transmit Spare Bits for National Use (Y, Sn, Sa) */ + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | + XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4); + break; + + case PC300_FR_UNFRAMED: + pfalc->multiframe_mode = 0; + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & + ~(FMR2_RFS1 | FMR2_RFS0)); + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_TT0); + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & + ~(XSW_XTM|XSW_XY0|XSW_XY1|XSW_XY2|XSW_XY3|XSW_XY4)); + cpc_writeb(falcbase + F_REG(TSWM, ch), 0xff); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | + (FMR2_RTM | FMR2_DAIS)); + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_AXRA); + cpc_writeb(falcbase + F_REG(FMR1, ch), + cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_AFR); + pfalc->sync = 1; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + break; + } + + /* No signaling */ + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN); + cpc_writeb(falcbase + F_REG(CCR1, ch), 0); + + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); + cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja)); + + /* Transmit Clock-Slot Offset */ + cpc_writeb(falcbase + F_REG(XC0, ch), + cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); + /* Transmit Time-slot Offset */ + cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e); + /* Receive Clock-Slot offset */ + cpc_writeb(falcbase + F_REG(RC0, ch), 0x05); + /* Receive Time-slot offset */ + cpc_writeb(falcbase + F_REG(RC1, ch), 0x00); + + /* LOS Detection after 176 consecutive 0s */ + cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a); + /* LOS Recovery after 22 ones in the time window of PCD */ + cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15); + + cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f); + + falc_close_all_timeslots(card, ch); +} + +static void falc_init_hdlc(pc300_t * card, int ch) +{ + void __iomem *falcbase = card->hw.falcbase; + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + /* Enable transparent data transfer */ + if (conf->fr_mode == PC300_FR_UNFRAMED) { + cpc_writeb(falcbase + F_REG(MODE, ch), 0); + } else { + cpc_writeb(falcbase + F_REG(MODE, ch), + cpc_readb(falcbase + F_REG(MODE, ch)) | + (MODE_HRAC | MODE_MDS2)); + cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff); + cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff); + } + + /* Tx/Rx reset */ + falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES); + + /* Enable interrupt sources */ + falc_intr_enable(card, ch); +} + +static void te_config(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 dummy; + unsigned long flags; + + memset(pfalc, 0, sizeof(falc_t)); + switch (conf->media) { + case IF_IFACE_T1: + pfalc->num_channels = NUM_OF_T1_CHANNELS; + pfalc->offset = 1; + break; + case IF_IFACE_E1: + pfalc->num_channels = NUM_OF_E1_CHANNELS; + pfalc->offset = 0; + break; + } + if (conf->tslot_bitmap == 0xffffffffUL) + pfalc->full_bandwidth = 1; + else + pfalc->full_bandwidth = 0; + + CPC_LOCK(card, flags); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + + if (conf->media == IF_IFACE_T1) { + falc_init_t1(card, ch); + } else { + falc_init_e1(card, ch); + } + falc_init_hdlc(card, ch); + if (conf->rx_sens == PC300_RX_SENS_SH) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON); + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON); + } + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2 * ch))); + + /* Clear all interrupt registers */ + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) + + cpc_readb(falcbase + F_REG(FISR1, ch)) + + cpc_readb(falcbase + F_REG(FISR2, ch)) + + cpc_readb(falcbase + F_REG(FISR3, ch)); + CPC_UNLOCK(card, flags); +} + +static void falc_check_status(pc300_t * card, int ch, unsigned char frs0) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + /* Verify LOS */ + if (frs0 & FRS0_LOS) { + if (!pfalc->red_alarm) { + pfalc->red_alarm = 1; + pfalc->los++; + if (!pfalc->blue_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere + * with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->red_alarm) { + pfalc->red_alarm = 0; + pfalc->losr++; + } + } + + if (conf->fr_mode != PC300_FR_UNFRAMED) { + /* Verify AIS alarm */ + if (frs0 & FRS0_AIS) { + if (!pfalc->blue_alarm) { + pfalc->blue_alarm = 1; + pfalc->ais++; + // EVENT_AIS + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_AIS + } + } else { + pfalc->blue_alarm = 0; + } + + /* Verify LFA */ + if (frs0 & FRS0_LFA) { + if (!pfalc->loss_fa) { + pfalc->loss_fa = 1; + pfalc->lfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + if (pfalc->loss_fa) { + pfalc->loss_fa = 0; + pfalc->farec++; + } + } + + /* Verify LMFA */ + if (pfalc->multiframe_mode && (frs0 & FRS0_LMFA)) { + /* D4 or CRC4 frame mode */ + if (!pfalc->loss_mfa) { + pfalc->loss_mfa = 1; + pfalc->lmfa++; + if (!pfalc->blue_alarm && !pfalc->red_alarm && + !pfalc->loss_fa) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise + * interfere with other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) + | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + } + } + } else { + pfalc->loss_mfa = 0; + } + + /* Verify Remote Alarm */ + if (frs0 & FRS0_RRA) { + if (!pfalc->yellow_alarm) { + pfalc->yellow_alarm = 1; + pfalc->rai++; + if (pfalc->sync) { + // EVENT_RAI + falc_disable_comm(card, ch); + // EVENT_RAI + } + } + } else { + pfalc->yellow_alarm = 0; + } + } /* if !PC300_UNFRAMED */ + + if (pfalc->red_alarm || pfalc->loss_fa || + pfalc->loss_mfa || pfalc->blue_alarm) { + if (pfalc->sync) { + pfalc->sync = 0; + chan->d.line_off++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } else { + if (!pfalc->sync) { + pfalc->sync = 1; + chan->d.line_on++; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED2 << (2 * ch))); + } + } + + if (pfalc->sync && !pfalc->yellow_alarm) { + if (!pfalc->active) { + // EVENT_FALC_NORMAL + if (pfalc->loop_active) { + return; + } + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN); + } + falc_enable_comm(card, ch); + // EVENT_FALC_NORMAL + pfalc->active = 1; + } + } else { + if (pfalc->active) { + pfalc->active = 0; + } + } +} + +static void falc_update_stats(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u16 counter; + + counter = cpc_readb(falcbase + F_REG(FECL, ch)); + counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8; + pfalc->fec += counter; + + counter = cpc_readb(falcbase + F_REG(CVCL, ch)); + counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8; + pfalc->cvc += counter; + + counter = cpc_readb(falcbase + F_REG(CECL, ch)); + counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8; + pfalc->cec += counter; + + counter = cpc_readb(falcbase + F_REG(EBCL, ch)); + counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8; + pfalc->ebc += counter; + + if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) { + mdelay(10); + counter = cpc_readb(falcbase + F_REG(BECL, ch)); + counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8; + pfalc->bec += counter; + + if (((conf->media == IF_IFACE_T1) && + (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) && + (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) || + ((conf->media == IF_IFACE_E1) && + (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) { + pfalc->prbs = 2; + } else { + pfalc->prbs = 1; + } + } +} + +/*---------------------------------------------------------------------------- + * falc_remote_loop + *---------------------------------------------------------------------------- + * Description: In the remote loopback mode the clock and data recovered + * from the line inputs RL1/2 or RDIP/RDIN are routed back + * to the line outputs XL1/2 or XDOP/XDON via the analog + * transmitter. As in normal mode they are processed by + * the synchronizer and then sent to the system interface. + *---------------------------------------------------------------------------- + */ +static void falc_remote_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM1, ch), + cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL); + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_local_loop + *---------------------------------------------------------------------------- + * Description: The local loopback mode disconnects the receive lines + * RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the + * signals coming from the line the data provided by system + * interface are routed through the analog receiver back to + * the system interface. The unipolar bit stream will be + * undisturbed transmitted on the line. Receiver and transmitter + * coding must be identical. + *---------------------------------------------------------------------------- + */ +static void falc_local_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL); + pfalc->loop_active = 1; + } else { + cpc_writeb(falcbase + F_REG(LIM0, ch), + cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * falc_payload_loop + *---------------------------------------------------------------------------- + * Description: This routine allows to enable/disable payload loopback. + * When the payload loop is activated, the received 192 bits + * of payload data will be looped back to the transmit + * direction. The framing bits, CRC6 and DL bits are not + * looped. They are originated by the FALC-LH transmitter. + *---------------------------------------------------------------------------- + */ +static void falc_payload_loop(pc300_t * card, int ch, int loop_on) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (loop_on) { + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0); + } + falc_open_all_timeslots(card, ch); + pfalc->loop_active = 2; + } else { + cpc_writeb(falcbase + F_REG(FMR2, ch), + cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB); + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR4, ch), + cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM); + } else { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; + falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_active = 0; + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xlu + *---------------------------------------------------------------------------- + * Description: Turns XLU bit off in the proper register + *---------------------------------------------------------------------------- + */ +static void turn_off_xlu(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU); + } +} + +/*---------------------------------------------------------------------------- + * turn_off_xld + *---------------------------------------------------------------------------- + * Description: Turns XLD bit off in the proper register + *---------------------------------------------------------------------------- + */ +static void turn_off_xld(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD); + } +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_up_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP activation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +static void falc_generate_loop_up_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU); + } + // EVENT_FALC_ABNORMAL + if (conf->media == IF_IFACE_T1) { + /* Disable this interrupt as it may otherwise interfere with + * other working boards. */ + cpc_writeb(falcbase + F_REG(IMR0, ch), + cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN); + } + falc_disable_comm(card, ch); + // EVENT_FALC_ABNORMAL + pfalc->loop_gen = 1; +} + +/*---------------------------------------------------------------------------- + * falc_generate_loop_down_code + *---------------------------------------------------------------------------- + * Description: This routine writes the proper FALC chip register in order + * to generate a LOOP deactivation code over a T1/E1 line. + *---------------------------------------------------------------------------- + */ +static void falc_generate_loop_down_code(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (conf->media == IF_IFACE_T1) { + cpc_writeb(falcbase + F_REG(FMR5, ch), + cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD); + } else { + cpc_writeb(falcbase + F_REG(FMR3, ch), + cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD); + } + pfalc->sync = 0; + cpc_writeb(falcbase + card->hw.cpld_reg2, + cpc_readb(falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED2 << (2 * ch))); + pfalc->active = 0; +//? falc_issue_cmd(card, ch, CMDR_XRES); + pfalc->loop_gen = 0; +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test + *---------------------------------------------------------------------------- + * Description: This routine generates a pattern code and checks + * it on the reception side. + *---------------------------------------------------------------------------- + */ +static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (activate) { + pfalc->prbs = 1; + pfalc->bec = 0; + if (conf->media == IF_IFACE_T1) { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC); + } else { + /* Disable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC); + } + /* Activates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS); + } else { + pfalc->prbs = 0; + /* Deactivates generation and monitoring of PRBS + * (Pseudo Random Bit Sequence) */ + cpc_writeb(falcbase + F_REG(LCR1, ch), + cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS)); + if (conf->media == IF_IFACE_T1) { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR3, ch), + cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC); + } else { + /* Enable local loop activation/deactivation detect */ + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC); + } + } +} + +/*---------------------------------------------------------------------------- + * falc_pattern_test_error + *---------------------------------------------------------------------------- + * Description: This routine returns the bit error counter value + *---------------------------------------------------------------------------- + */ +static u16 falc_pattern_test_error(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + + return pfalc->bec; +} + +/**********************************/ +/*** Net Interface Routines ***/ +/**********************************/ + +static void +cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) { + printk("%s: out of memory\n", dev->name); + return; + } + skb_put(skb, 10 + skb_main->len); + + skb->dev = dev; + skb->protocol = htons(ETH_P_CUST); + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_HOST; + skb->len = 10 + skb_main->len; + + skb_copy_to_linear_data(skb, dev->name, 5); + skb->data[5] = '['; + skb->data[6] = rx_tx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + skb_copy_from_linear_data(skb_main, &skb->data[10], skb_main->len); + + netif_rx(skb); +} + +static void cpc_tx_timeout(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; + unsigned long flags; + u8 ilar; + + dev->stats.tx_errors++; + dev->stats.tx_aborted_errors++; + CPC_LOCK(card, flags); + if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) { + printk("%s: ILAR=0x%x\n", dev->name, ilar); + cpc_writeb(card->hw.scabase + ILAR, ilar); + cpc_writeb(card->hw.scabase + DMER, 0x80); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + dev->trans_start = jiffies; /* prevent tx timeout */ + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); +} + +static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; + unsigned long flags; +#ifdef PC300_DEBUG_TX + int i; +#endif + + if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + dev_kfree_skb(skb); + dev->stats.tx_errors++; + dev->stats.tx_carrier_errors++; + return 0; + } else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk("%s: DCD is OFF. Going administrative down.\n", dev->name); + dev->stats.tx_errors++; + dev->stats.tx_carrier_errors++; + dev_kfree_skb(skb); + netif_carrier_off(dev); + CPC_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + netif_wake_queue(dev); + return 0; + } + + /* Write buffer to DMA buffers */ + if (dma_buf_write(card, ch, (u8 *)skb->data, skb->len) != 0) { +// printk("%s: write error. Dropping TX packet.\n", dev->name); + netif_stop_queue(dev); + dev_kfree_skb(skb); + dev->stats.tx_errors++; + dev->stats.tx_dropped++; + return 0; + } +#ifdef PC300_DEBUG_TX + printk("%s T:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + + if (d->trace_on) { + cpc_trace(dev, skb, 'T'); + } + + /* Start transmission */ + CPC_LOCK(card, flags); + /* verify if it has more than one free descriptor */ + if (card->chan[ch].nfree_tx_bd <= 1) { + /* don't have so stop the queue */ + netif_stop_queue(dev); + } + cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_UNLOCK(card, flags); + dev_kfree_skb(skb); + + return 0; +} + +static void cpc_net_rx(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel; +#ifdef PC300_DEBUG_RX + int i; +#endif + int rxb; + struct sk_buff *skb; + + while (1) { + if ((rxb = dma_get_rx_frame_size(card, ch)) == -1) + return; + + if (!netif_carrier_ok(dev)) { + /* DCD must be OFF: drop packet */ + printk("%s : DCD is OFF - drop %d rx bytes\n", dev->name, rxb); + skb = NULL; + } else { + if (rxb > (dev->mtu + 40)) { /* add headers */ + printk("%s : MTU exceeded %d\n", dev->name, rxb); + skb = NULL; + } else { + skb = dev_alloc_skb(rxb); + if (skb == NULL) { + printk("%s: Memory squeeze!!\n", dev->name); + return; + } + skb->dev = dev; + } + } + + if (((rxb = dma_buf_read(card, ch, skb)) <= 0) || (skb == NULL)) { +#ifdef PC300_DEBUG_RX + printk("%s: rxb = %x\n", dev->name, rxb); +#endif + if ((skb == NULL) && (rxb > 0)) { + /* rxb > dev->mtu */ + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; + continue; + } + + if (rxb < 0) { /* Invalid frame */ + rxb = -rxb; + if (rxb & DST_OVR) { + dev->stats.rx_errors++; + dev->stats.rx_fifo_errors++; + } + if (rxb & DST_CRC) { + dev->stats.rx_errors++; + dev->stats.rx_crc_errors++; + } + if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) { + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; + } + } + if (skb) { + dev_kfree_skb_irq(skb); + } + continue; + } + + dev->stats.rx_bytes += rxb; + +#ifdef PC300_DEBUG_RX + printk("%s R:", dev->name); + for (i = 0; i < skb->len; i++) + printk(" %02x", *(skb->data + i)); + printk("\n"); +#endif + if (d->trace_on) { + cpc_trace(dev, skb, 'R'); + } + dev->stats.rx_packets++; + skb->protocol = hdlc_type_trans(skb, dev); + netif_rx(skb); + } +} + +/************************************/ +/*** PC300 Interrupt Routines ***/ +/************************************/ +static void sca_tx_intr(pc300dev_t *dev) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + volatile pcsca_bd_t __iomem * ptdescr; + + /* Clean up descriptors from previous transmission */ + ptdescr = (card->hw.rambase + + TX_BD_ADDR(ch,chan->tx_first_bd)); + while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) != + TX_BD_ADDR(ch,chan->tx_first_bd)) && + (cpc_readb(&ptdescr->status) & DST_OSB)) { + dev->dev->stats.tx_packets++; + dev->dev->stats.tx_bytes += cpc_readw(&ptdescr->len); + cpc_writeb(&ptdescr->status, DST_OSB); + cpc_writew(&ptdescr->len, 0); + chan->nfree_tx_bd++; + chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1); + ptdescr = (card->hw.rambase + TX_BD_ADDR(ch,chan->tx_first_bd)); + } + +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_trigger_poll(dev); + } else { +#endif + /* Tell the upper layer we are ready to transmit more packets */ + netif_wake_queue(dev->dev); +#ifdef CONFIG_PC300_MLPPP + } +#endif +} + +static void sca_intr(pc300_t * card) +{ + void __iomem *scabase = card->hw.scabase; + volatile u32 status; + int ch; + int intr_count = 0; + unsigned char dsr_rx; + + while ((status = cpc_readl(scabase + ISR0)) != 0) { + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300dev_t *d = &chan->d; + struct net_device *dev = d->dev; + + spin_lock(&card->card_lock); + + /**** Reception ****/ + if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) { + u8 drx_stat = cpc_readb(scabase + DSR_RX(ch)); + + /* Clear RX interrupts */ + cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, drx_stat); +#endif + if (status & IR0_DRX(IR0_DMIA, ch)) { + if (drx_stat & DSR_BOF) { +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_tty_receive(d); + rx_dma_start(card, ch); + } else +#endif + { + if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { + rx_dma_stop(card, ch); + } + cpc_net_rx(dev); + /* Discard invalid frames */ + dev->stats.rx_errors++; + dev->stats.rx_over_errors++; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_start(card, ch); + } + } + } + if (status & IR0_DRX(IR0_DMIB, ch)) { + if (drx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + /* verify if driver is TTY */ + cpc_tty_receive(d); + } else { + cpc_net_rx(dev); + } +#else + cpc_net_rx(dev); +#endif + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + } + } + if (!(dsr_rx = cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) { +#ifdef PC300_DEBUG_INTR + printk("%s: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x, dsr2=0x%02x)\n", + dev->name, ch, status, drx_stat, dsr_rx); +#endif + cpc_writeb(scabase + DSR_RX(ch), (dsr_rx | DSR_DE) & 0xfe); + } + } + + /**** Transmission ****/ + if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) { + u8 dtx_stat = cpc_readb(scabase + DSR_TX(ch)); + + /* Clear TX interrupts */ + cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE); + +#ifdef PC300_DEBUG_INTR + printk ("sca_intr: TX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n", + ch, status, dtx_stat); +#endif + if (status & IR0_DTX(IR0_EFT, ch)) { + if (dtx_stat & DSR_UDRF) { + if (cpc_readb (scabase + M_REG(TBN, ch)) != 0) { + cpc_writeb(scabase + M_REG(CMD,ch), CMD_TX_BUF_CLR); + } + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + dev->stats.tx_errors++; + dev->stats.tx_fifo_errors++; + sca_tx_intr(d); + } + } + if (status & IR0_DTX(IR0_DMIA, ch)) { + if (dtx_stat & DSR_BOF) { + } + } + if (status & IR0_DTX(IR0_DMIB, ch)) { + if (dtx_stat & DSR_EOM) { + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb (card->hw.falcbase + + card->hw.cpld_reg2) & + ~ (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + sca_tx_intr(d); + } + } + } + + /**** MSCI ****/ + if (status & IR0_M(IR0_RXINTA, ch)) { + u8 st1 = cpc_readb(scabase + M_REG(ST1, ch)); + + /* Clear MSCI interrupts */ + cpc_writeb(scabase + M_REG(ST1, ch), st1); + +#ifdef PC300_DEBUG_INTR + printk("sca_intr: MSCI intr chan[%d] (st=0x%08lx, st1=0x%02x)\n", + ch, status, st1); +#endif + if (st1 & ST1_CDCD) { /* DCD changed */ + if (cpc_readb(scabase + M_REG(ST3, ch)) & ST3_DCD) { + printk ("%s: DCD is OFF. Going administrative down.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) { + netif_carrier_off(dev); + } +#else + netif_carrier_off(dev); + +#endif + card->chan[ch].d.line_off++; + } else { /* DCD = 1 */ + printk ("%s: DCD is ON. Going administrative up.\n", + dev->name); +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto != PC300_PROTO_MLPPP) + /* verify if driver is not TTY */ +#endif + netif_carrier_on(dev); + card->chan[ch].d.line_on++; + } + } + } + spin_unlock(&card->card_lock); + } + if (++intr_count == 10) + /* Too much work at this board. Force exit */ + break; + } +} + +static void falc_t1_loop_detection(pc300_t *card, int ch, u8 frs1) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (frs1 & FRS1_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((frs1 & FRS1_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_e1_loop_detection(pc300_t *card, int ch, u8 rsp) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + + if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && + !pfalc->loop_gen) { + if (rsp & RSP_LLBDD) { + // A Line Loop Back Deactivation signal detected + if (pfalc->loop_active) { + falc_remote_loop(card, ch, 0); + } + } else { + if ((rsp & RSP_LLBAD) && + ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) { + // A Line Loop Back Activation signal detected + if (!pfalc->loop_active) { + falc_remote_loop(card, ch, 1); + } + } + } + } +} + +static void falc_t1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 isr0, isr3, gis; + u8 dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + if (gis & GIS_ISR0) { + isr0 = cpc_readb(falcbase + F_REG(FISR0, ch)); + if (isr0 & FISR0_PDEN) { + /* Read the bit to clear the situation */ + if (cpc_readb(falcbase + F_REG(FRS1, ch)) & + FRS1_PDEN) { + pfalc->pden++; + } + } + } + + if (gis & GIS_ISR1) { + dummy = cpc_readb(falcbase + F_REG(FISR1, ch)); + } + + if (gis & GIS_ISR2) { + dummy = cpc_readb(falcbase + F_REG(FISR2, ch)); + } + + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + if (isr3 & FISR3_LLBSC) { + falc_t1_loop_detection(card, ch, + cpc_readb(falcbase + F_REG(FRS1, ch))); + } + } + } +} + +static void falc_e1_intr(pc300_t * card, int ch) +{ + pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + void __iomem *falcbase = card->hw.falcbase; + u8 isr1, isr2, isr3, gis, rsp; + u8 dummy; + + while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) { + rsp = cpc_readb(falcbase + F_REG(RSP, ch)); + + if (gis & GIS_ISR0) { + dummy = cpc_readb(falcbase + F_REG(FISR0, ch)); + } + if (gis & GIS_ISR1) { + isr1 = cpc_readb(falcbase + F_REG(FISR1, ch)); + if (isr1 & FISR1_XMB) { + if ((pfalc->xmb_cause & 2) && + pfalc->multiframe_mode) { + if (cpc_readb (falcbase + F_REG(FRS0, ch)) & + (FRS0_LOS | FRS0_AIS | FRS0_LFA)) { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + & ~XSP_AXS); + } else { + cpc_writeb(falcbase + F_REG(XSP, ch), + cpc_readb(falcbase + F_REG(XSP, ch)) + | XSP_AXS); + } + } + pfalc->xmb_cause = 0; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB); + } + if (isr1 & FISR1_LLBSC) { + falc_e1_loop_detection(card, ch, rsp); + } + } + if (gis & GIS_ISR2) { + isr2 = cpc_readb(falcbase + F_REG(FISR2, ch)); + if (isr2 & FISR2_T400MS) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA); + } + if (isr2 & FISR2_MFAR) { + cpc_writeb(falcbase + F_REG(XSW, ch), + cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA); + } + if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) { + pfalc->xmb_cause |= 2; + cpc_writeb(falcbase + F_REG(IMR1, ch), + cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB); + } + } + if (gis & GIS_ISR3) { + isr3 = cpc_readb(falcbase + F_REG(FISR3, ch)); + if (isr3 & FISR3_SEC) { + pfalc->sec++; + falc_update_stats(card, ch); + falc_check_status(card, ch, + cpc_readb(falcbase + F_REG(FRS0, ch))); + } + if (isr3 & FISR3_ES) { + pfalc->es++; + } + } + } +} + +static void falc_intr(pc300_t * card) +{ + int ch; + + for (ch = 0; ch < card->hw.nchan; ch++) { + pc300ch_t *chan = &card->chan[ch]; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + + if (conf->media == IF_IFACE_T1) { + falc_t1_intr(card, ch); + } else { + falc_e1_intr(card, ch); + } + } +} + +static irqreturn_t cpc_intr(int irq, void *dev_id) +{ + pc300_t *card = dev_id; + volatile u8 plx_status; + + if (!card) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr %d\n", irq); +#endif + return IRQ_NONE; /* spurious intr */ + } + + if (!card->hw.rambase) { +#ifdef PC300_DEBUG_INTR + printk("cpc_intr: spurious intr2 %d\n", irq); +#endif + return IRQ_NONE; /* spurious intr */ + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + sca_intr(card); + break; + + case PC300_TE: + while ( (plx_status = (cpc_readb(card->hw.plxbase + card->hw.intctl_reg) & + (PLX_9050_LINT1_STATUS | PLX_9050_LINT2_STATUS))) != 0) { + if (plx_status & PLX_9050_LINT1_STATUS) { /* SCA Interrupt */ + sca_intr(card); + } + if (plx_status & PLX_9050_LINT2_STATUS) { /* FALC Interrupt */ + falc_intr(card); + } + } + break; + } + return IRQ_HANDLED; +} + +static void cpc_sca_status(pc300_t * card, int ch) +{ + u8 ilar; + void __iomem *scabase = card->hw.scabase; + unsigned long flags; + + tx_dma_buf_check(card, ch); + rx_dma_buf_check(card, ch); + ilar = cpc_readb(scabase + ILAR); + printk ("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n", + ilar, cpc_readb(scabase + WCRL), cpc_readb(scabase + PCR), + cpc_readb(scabase + BTCR), cpc_readb(scabase + BOLR)); + printk("TX_CDA=0x%08x, TX_EDA=0x%08x\n", + cpc_readl(scabase + DTX_REG(CDAL, ch)), + cpc_readl(scabase + DTX_REG(EDAL, ch))); + printk("RX_CDA=0x%08x, RX_EDA=0x%08x, BFL=0x%04x\n", + cpc_readl(scabase + DRX_REG(CDAL, ch)), + cpc_readl(scabase + DRX_REG(EDAL, ch)), + cpc_readw(scabase + DRX_REG(BFLL, ch))); + printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n", + cpc_readb(scabase + DMER), cpc_readb(scabase + DSR_TX(ch)), + cpc_readb(scabase + DSR_RX(ch))); + printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n", + cpc_readb(scabase + DMR_TX(ch)), cpc_readb(scabase + DMR_RX(ch)), + cpc_readb(scabase + DIR_TX(ch)), + cpc_readb(scabase + DIR_RX(ch))); + printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n", + cpc_readb(scabase + DCR_TX(ch)), cpc_readb(scabase + DCR_RX(ch)), + cpc_readb(scabase + FCT_TX(ch)), + cpc_readb(scabase + FCT_RX(ch))); + printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n", + cpc_readb(scabase + M_REG(MD0, ch)), + cpc_readb(scabase + M_REG(MD1, ch)), + cpc_readb(scabase + M_REG(MD2, ch)), + cpc_readb(scabase + M_REG(MD3, ch)), + cpc_readb(scabase + M_REG(IDL, ch))); + printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n", + cpc_readb(scabase + M_REG(CMD, ch)), + cpc_readb(scabase + M_REG(SA0, ch)), + cpc_readb(scabase + M_REG(SA1, ch)), + cpc_readb(scabase + M_REG(TFN, ch)), + cpc_readb(scabase + M_REG(CTL, ch))); + printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n", + cpc_readb(scabase + M_REG(ST0, ch)), + cpc_readb(scabase + M_REG(ST1, ch)), + cpc_readb(scabase + M_REG(ST2, ch)), + cpc_readb(scabase + M_REG(ST3, ch)), + cpc_readb(scabase + M_REG(ST4, ch))); + printk ("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n", + cpc_readb(scabase + M_REG(CST0, ch)), + cpc_readb(scabase + M_REG(CST1, ch)), + cpc_readb(scabase + M_REG(CST2, ch)), + cpc_readb(scabase + M_REG(CST3, ch)), + cpc_readb(scabase + M_REG(FST, ch))); + printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n", + cpc_readb(scabase + M_REG(TRC0, ch)), + cpc_readb(scabase + M_REG(TRC1, ch)), + cpc_readb(scabase + M_REG(RRC, ch)), + cpc_readb(scabase + M_REG(TBN, ch)), + cpc_readb(scabase + M_REG(RBN, ch))); + printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TFS, ch)), + cpc_readb(scabase + M_REG(TNR0, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n", + cpc_readb(scabase + M_REG(TCR, ch)), + cpc_readb(scabase + M_REG(RCR, ch)), + cpc_readb(scabase + M_REG(TNR1, ch)), + cpc_readb(scabase + M_REG(RNR, ch))); + printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n", + cpc_readb(scabase + M_REG(TXS, ch)), + cpc_readb(scabase + M_REG(RXS, ch)), + cpc_readb(scabase + M_REG(EXS, ch)), + cpc_readb(scabase + M_REG(TMCT, ch)), + cpc_readb(scabase + M_REG(TMCR, ch))); + printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n", + cpc_readb(scabase + M_REG(IE0, ch)), + cpc_readb(scabase + M_REG(IE1, ch)), + cpc_readb(scabase + M_REG(IE2, ch)), + cpc_readb(scabase + M_REG(IE4, ch)), + cpc_readb(scabase + M_REG(FIE, ch))); + printk("IER0=0x%08x\n", cpc_readl(scabase + IER0)); + + if (ilar != 0) { + CPC_LOCK(card, flags); + cpc_writeb(scabase + ILAR, ilar); + cpc_writeb(scabase + DMER, 0x80); + CPC_UNLOCK(card, flags); + } +} + +static void cpc_falc_status(pc300_t * card, int ch) +{ + pc300ch_t *chan = &card->chan[ch]; + falc_t *pfalc = (falc_t *) & chan->falc; + unsigned long flags; + + CPC_LOCK(card, flags); + printk("CH%d: %s %s %d channels\n", + ch, (pfalc->sync ? "SYNC" : ""), (pfalc->active ? "ACTIVE" : ""), + pfalc->num_channels); + + printk(" pden=%d, los=%d, losr=%d, lfa=%d, farec=%d\n", + pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec); + printk(" lmfa=%d, ais=%d, sec=%d, es=%d, rai=%d\n", + pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai); + printk(" bec=%d, fec=%d, cvc=%d, cec=%d, ebc=%d\n", + pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc); + + printk("\n"); + printk(" STATUS: %s %s %s %s %s %s\n", + (pfalc->red_alarm ? "RED" : ""), + (pfalc->blue_alarm ? "BLU" : ""), + (pfalc->yellow_alarm ? "YEL" : ""), + (pfalc->loss_fa ? "LFA" : ""), + (pfalc->loss_mfa ? "LMF" : ""), (pfalc->prbs ? "PRB" : "")); + CPC_UNLOCK(card, flags); +} + +static int cpc_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + pc300conf_t conf_aux; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + int ch = chan->channel; + void __user *arg = ifr->ifr_data; + struct if_settings *settings = &ifr->ifr_settings; + void __iomem *scabase = card->hw.scabase; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + switch (cmd) { + case SIOCGPC300CONF: +#ifdef CONFIG_PC300_MLPPP + if (conf->proto != PC300_PROTO_MLPPP) { + conf->proto = /* FIXME hdlc->proto.id */ 0; + } +#else + conf->proto = /* FIXME hdlc->proto.id */ 0; +#endif + memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t)); + memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t)); + if (!arg || + copy_to_user(arg, &conf_aux, sizeof(pc300conf_t))) + return -EINVAL; + return 0; + case SIOCSPC300CONF: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (!arg || + copy_from_user(&conf_aux.conf, arg, sizeof(pc300chconf_t))) + return -EINVAL; + if (card->hw.cpld_id < 0x02 && + conf_aux.conf.fr_mode == PC300_FR_UNFRAMED) { + /* CPLD_ID < 0x02 doesn't support Unframed E1 */ + return -EINVAL; + } +#ifdef CONFIG_PC300_MLPPP + if (conf_aux.conf.proto == PC300_PROTO_MLPPP) { + if (conf->proto != PC300_PROTO_MLPPP) { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + cpc_tty_init(d); /* init TTY driver */ + } + } else { + if (conf_aux.conf.proto == 0xffff) { + if (conf->proto == PC300_PROTO_MLPPP){ + /* ifdown interface */ + cpc_close(dev); + } + } else { + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + /* FIXME hdlc->proto.id = conf->proto; */ + } + } +#else + memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t)); + /* FIXME hdlc->proto.id = conf->proto; */ +#endif + return 0; + case SIOCGPC300STATUS: + cpc_sca_status(card, ch); + return 0; + case SIOCGPC300FALCSTATUS: + cpc_falc_status(card, ch); + return 0; + + case SIOCGPC300UTILSTATS: + { + if (!arg) { /* clear statistics */ + memset(&dev->stats, 0, sizeof(dev->stats)); + if (card->hw.type == PC300_TE) { + memset(&chan->falc, 0, sizeof(falc_t)); + } + } else { + pc300stats_t pc300stats; + + memset(&pc300stats, 0, sizeof(pc300stats_t)); + pc300stats.hw_type = card->hw.type; + pc300stats.line_on = card->chan[ch].d.line_on; + pc300stats.line_off = card->chan[ch].d.line_off; + memcpy(&pc300stats.gen_stats, &dev->stats, + sizeof(dev->stats)); + if (card->hw.type == PC300_TE) + memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t)); + if (copy_to_user(arg, &pc300stats, sizeof(pc300stats_t))) + return -EFAULT; + } + return 0; + } + + case SIOCGPC300UTILSTATUS: + { + struct pc300status pc300status; + + pc300status.hw_type = card->hw.type; + if (card->hw.type == PC300_TE) { + pc300status.te_status.sync = chan->falc.sync; + pc300status.te_status.red_alarm = chan->falc.red_alarm; + pc300status.te_status.blue_alarm = chan->falc.blue_alarm; + pc300status.te_status.loss_fa = chan->falc.loss_fa; + pc300status.te_status.yellow_alarm =chan->falc.yellow_alarm; + pc300status.te_status.loss_mfa = chan->falc.loss_mfa; + pc300status.te_status.prbs = chan->falc.prbs; + } else { + pc300status.gen_status.dcd = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_DCD); + pc300status.gen_status.cts = + !(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_CTS); + pc300status.gen_status.rts = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_RTS); + pc300status.gen_status.dtr = + !(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR); + /* There is no DSR in HD64572 */ + } + if (!arg || + copy_to_user(arg, &pc300status, sizeof(pc300status_t))) + return -EINVAL; + return 0; + } + + case SIOCSPC300TRACE: + /* Sets/resets a trace_flag for the respective device */ + if (!arg || copy_from_user(&d->trace_on, arg,sizeof(unsigned char))) + return -EINVAL; + return 0; + + case SIOCSPC300LOOPBACK: + { + struct pc300loopback pc300loop; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (!arg || + copy_from_user(&pc300loop, arg, sizeof(pc300loopback_t))) + return -EINVAL; + switch (pc300loop.loop_type) { + case PC300LOCLOOP: /* Turn the local loop on/off */ + falc_local_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300REMLOOP: /* Turn the remote loop on/off */ + falc_remote_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300PAYLOADLOOP: /* Turn the payload loop on/off */ + falc_payload_loop(card, ch, pc300loop.loop_on); + return 0; + + case PC300GENLOOPUP: /* Generate loop UP */ + if (pc300loop.loop_on) { + falc_generate_loop_up_code (card, ch); + } else { + turn_off_xlu(card, ch); + } + return 0; + + case PC300GENLOOPDOWN: /* Generate loop DOWN */ + if (pc300loop.loop_on) { + falc_generate_loop_down_code (card, ch); + } else { + turn_off_xld(card, ch); + } + return 0; + + default: + return -EINVAL; + } + } + + case SIOCSPC300PATTERNTEST: + /* Turn the pattern test on/off and show the errors counter */ + { + struct pc300patterntst pc300patrntst; + + /* TE boards only */ + if (card->hw.type != PC300_TE) + return -EINVAL; + + if (card->hw.cpld_id < 0x02) { + /* CPLD_ID < 0x02 doesn't support pattern test */ + return -EINVAL; + } + + if (!arg || + copy_from_user(&pc300patrntst,arg,sizeof(pc300patterntst_t))) + return -EINVAL; + if (pc300patrntst.patrntst_on == 2) { + if (chan->falc.prbs == 0) { + falc_pattern_test(card, ch, 1); + } + pc300patrntst.num_errors = + falc_pattern_test_error(card, ch); + if (copy_to_user(arg, &pc300patrntst, + sizeof(pc300patterntst_t))) + return -EINVAL; + } else { + falc_pattern_test(card, ch, pc300patrntst.patrntst_on); + } + return 0; + } + + case SIOCWANDEV: + switch (ifr->ifr_settings.type) { + case IF_GET_IFACE: + { + const size_t size = sizeof(sync_serial_settings); + ifr->ifr_settings.type = conf->media; + if (ifr->ifr_settings.size < size) { + /* data size wanted */ + ifr->ifr_settings.size = size; + return -ENOBUFS; + } + + if (copy_to_user(settings->ifs_ifsu.sync, + &conf->phys_settings, size)) { + return -EFAULT; + } + return 0; + } + + case IF_IFACE_V35: + case IF_IFACE_V24: + case IF_IFACE_X21: + { + const size_t size = sizeof(sync_serial_settings); + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + /* incorrect data len? */ + if (ifr->ifr_settings.size != size) { + return -ENOBUFS; + } + + if (copy_from_user(&conf->phys_settings, + settings->ifs_ifsu.sync, size)) { + return -EFAULT; + } + + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + + case IF_IFACE_T1: + case IF_IFACE_E1: + { + const size_t te_size = sizeof(te1_settings); + const size_t size = sizeof(sync_serial_settings); + + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + + /* incorrect data len? */ + if (ifr->ifr_settings.size != te_size) { + return -ENOBUFS; + } + + if (copy_from_user(&conf->phys_settings, + settings->ifs_ifsu.te1, size)) { + return -EFAULT; + }/* Ignoring HDLC slot_map for a while */ + + if (conf->phys_settings.loopback) { + cpc_writeb(card->hw.scabase + M_REG(MD2, ch), + cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | + MD2_LOOP_MIR); + } + conf->media = ifr->ifr_settings.type; + return 0; + } + default: + return hdlc_ioctl(dev, ifr, cmd); + } + + default: + return hdlc_ioctl(dev, ifr, cmd); + } +} + +static int clock_rate_calc(u32 rate, u32 clock, int *br_io) +{ + int br, tc; + int br_pwr, error; + + *br_io = 0; + + if (rate == 0) + return 0; + + for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { + if ((tc = clock / br_pwr / rate) <= 0xff) { + *br_io = br; + break; + } + } + + if (tc <= 0xff) { + error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; + /* Errors bigger than +/- 1% won't be tolerated */ + if (error < -10 || error > 10) + return -1; + else + return tc; + } else { + return -1; + } +} + +static int ch_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300chconf_t *conf = (pc300chconf_t *) & chan->conf; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + void __iomem *plxbase = card->hw.plxbase; + int ch = chan->channel; + u32 clkrate = chan->conf.phys_settings.clock_rate; + u32 clktype = chan->conf.phys_settings.clock_type; + u16 encoding = chan->conf.proto_settings.encoding; + u16 parity = chan->conf.proto_settings.parity; + u8 md0, md2; + + /* Reset the channel */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST); + + /* Configure the SCA registers */ + switch (parity) { + case PARITY_NONE: + md0 = MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR0: + md0 = MD0_CRC16_0|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1: + md0 = MD0_CRC16_1|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC32_PR1_CCITT: + md0 = MD0_CRC32|MD0_CRCC0|MD0_BIT_SYNC; + break; + case PARITY_CRC16_PR1_CCITT: + default: + md0 = MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC; + break; + } + switch (encoding) { + case ENCODING_NRZI: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZI; + break; + case ENCODING_FM_MARK: /* FM1 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM1; + break; + case ENCODING_FM_SPACE: /* FM0 */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM0; + break; + case ENCODING_MANCHESTER: /* It's not working... */ + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_MANCH; + break; + case ENCODING_NRZ: + default: + md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZ; + break; + } + cpc_writeb(scabase + M_REG(MD0, ch), md0); + cpc_writeb(scabase + M_REG(MD1, ch), 0); + cpc_writeb(scabase + M_REG(MD2, ch), md2); + cpc_writeb(scabase + M_REG(IDL, ch), 0x7e); + cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP | CTL_IDLC); + + /* Configure HW media */ + switch (card->hw.type) { + case PC300_RSV: + if (conf->media == IF_IFACE_V35) { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) | PC300_CHMEDIA_MASK(ch)); + } else { + cpc_writel((plxbase + card->hw.gpioc_reg), + cpc_readl(plxbase + card->hw.gpioc_reg) & ~PC300_CHMEDIA_MASK(ch)); + } + break; + + case PC300_X21: + break; + + case PC300_TE: + te_config(card, ch); + break; + } + + switch (card->hw.type) { + case PC300_RSV: + case PC300_X21: + if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) { + int tmc, br; + + /* Calculate the clkrate parameters */ + tmc = clock_rate_calc(clkrate, card->hw.clock, &br); + if (tmc < 0) + return -EIO; + cpc_writeb(scabase + M_REG(TMCT, ch), tmc); + cpc_writeb(scabase + M_REG(TXS, ch), + (TXS_DTRXC | TXS_IBRG | br)); + if (clktype == CLOCK_INT) { + cpc_writeb(scabase + M_REG(TMCR, ch), tmc); + cpc_writeb(scabase + M_REG(RXS, ch), + (RXS_IBRG | br)); + } else { + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + } + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 1); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } else { + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + if (clktype == CLOCK_EXT) { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC); + } else { + cpc_writeb(scabase + M_REG(TXS, ch), + TXS_DTRXC|TXS_RCLK); + } + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + if (card->hw.type == PC300_X21) { + cpc_writeb(scabase + M_REG(GPO, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1); + } else { + cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1); + } + } + break; + + case PC300_TE: + /* SCA always receives clock from the FALC chip */ + cpc_writeb(scabase + M_REG(TMCT, ch), 1); + cpc_writeb(scabase + M_REG(TXS, ch), 0); + cpc_writeb(scabase + M_REG(TMCR, ch), 1); + cpc_writeb(scabase + M_REG(RXS, ch), 0); + cpc_writeb(scabase + M_REG(EXS, ch), 0); + break; + } + + /* Enable Interrupts */ + cpc_writel(scabase + IER0, + cpc_readl(scabase + IER0) | + IR0_M(IR0_RXINTA, ch) | + IR0_DRX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch) | + IR0_DTX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch)); + cpc_writeb(scabase + M_REG(IE0, ch), + cpc_readl(scabase + M_REG(IE0, ch)) | IE0_RXINTA); + cpc_writeb(scabase + M_REG(IE1, ch), + cpc_readl(scabase + M_REG(IE1, ch)) | IE1_CDCD); + + return 0; +} + +static int rx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_RX(ch), 0); + + /* General RX settings */ + cpc_writeb(scabase + M_REG(RRC, ch), 0); + cpc_writeb(scabase + M_REG(RNR, ch), 16); + + /* Enable reception */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT); + cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA); + + /* Initialize DMA stuff */ + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + rx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF)); + + /* Start DMA */ + rx_dma_start(card, ch); + + return 0; +} + +static int tx_config(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + void __iomem *scabase = card->hw.scabase; + int ch = chan->channel; + + cpc_writeb(scabase + DSR_TX(ch), 0); + + /* General TX settings */ + cpc_writeb(scabase + M_REG(TRC0, ch), 0); + cpc_writeb(scabase + M_REG(TFS, ch), 32); + cpc_writeb(scabase + M_REG(TNR0, ch), 20); + cpc_writeb(scabase + M_REG(TNR1, ch), 48); + cpc_writeb(scabase + M_REG(TCR, ch), 8); + + /* Enable transmission */ + cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT); + + /* Initialize DMA stuff */ + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + tx_dma_buf_init(card, ch); + cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR); + cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF)); + cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF)); + cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd)); + cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd)); + + return 0; +} + +static int cpc_attach(struct net_device *dev, unsigned short encoding, + unsigned short parity) +{ + pc300dev_t *d = (pc300dev_t *)dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *)d->chan; + pc300_t *card = (pc300_t *)chan->card; + pc300chconf_t *conf = (pc300chconf_t *)&chan->conf; + + if (card->hw.type == PC300_TE) { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI) { + return -EINVAL; + } + } else { + if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI && + encoding != ENCODING_FM_MARK && encoding != ENCODING_FM_SPACE) { + /* Driver doesn't support ENCODING_MANCHESTER yet */ + return -EINVAL; + } + } + + if (parity != PARITY_NONE && parity != PARITY_CRC16_PR0 && + parity != PARITY_CRC16_PR1 && parity != PARITY_CRC32_PR1_CCITT && + parity != PARITY_CRC16_PR1_CCITT) { + return -EINVAL; + } + + conf->proto_settings.encoding = encoding; + conf->proto_settings.parity = parity; + return 0; +} + +static int cpc_opench(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + int ch = chan->channel, rc; + void __iomem *scabase = card->hw.scabase; + + rc = ch_config(d); + if (rc) + return rc; + + rx_config(d); + + tx_config(d); + + /* Assert RTS and DTR */ + cpc_writeb(scabase + M_REG(CTL, ch), + cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR)); + + return 0; +} + +static void cpc_closech(pc300dev_t * d) +{ + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + falc_t *pfalc = (falc_t *) & chan->falc; + int ch = chan->channel; + + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST); + rx_dma_stop(card, ch); + tx_dma_stop(card, ch); + + if (card->hw.type == PC300_TE) { + memset(pfalc, 0, sizeof(falc_t)); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK | + CPLD_REG2_FALC_LED2) << (2 * ch))); + /* Reset the FALC chip */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + (CPLD_REG1_FALC_RESET << (2 * ch))); + udelay(10000); + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) & + ~(CPLD_REG1_FALC_RESET << (2 * ch))); + } +} + +int cpc_open(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + struct ifreq ifr; + int result; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_open"); +#endif + + result = hdlc_open(dev); + + if (result) + return result; + + sprintf(ifr.ifr_name, "%s", dev->name); + result = cpc_opench(d); + if (result) + goto err_out; + + netif_start_queue(dev); + return 0; + +err_out: + hdlc_close(dev); + return result; +} + +static int cpc_close(struct net_device *dev) +{ + pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv; + pc300ch_t *chan = (pc300ch_t *) d->chan; + pc300_t *card = (pc300_t *) chan->card; + unsigned long flags; + +#ifdef PC300_DEBUG_OTHER + printk("pc300: cpc_close"); +#endif + + netif_stop_queue(dev); + + CPC_LOCK(card, flags); + cpc_closech(d); + CPC_UNLOCK(card, flags); + + hdlc_close(dev); + +#ifdef CONFIG_PC300_MLPPP + if (chan->conf.proto == PC300_PROTO_MLPPP) { + cpc_tty_unregister_service(d); + chan->conf.proto = 0xffff; + } +#endif + + return 0; +} + +static u32 detect_ram(pc300_t * card) +{ + u32 i; + u8 data; + void __iomem *rambase = card->hw.rambase; + + card->hw.ramsize = PC300_RAMSIZE; + /* Let's find out how much RAM is present on this board */ + for (i = 0; i < card->hw.ramsize; i++) { + data = (u8)(i & 0xff); + cpc_writeb(rambase + i, data); + if (cpc_readb(rambase + i) != data) { + break; + } + } + return i; +} + +static void plx_init(pc300_t * card) +{ + struct RUNTIME_9050 __iomem *plx_ctl = card->hw.plxbase; + + /* Reset PLX */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x40000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x40000000); + + /* Reload Config. Registers from EEPROM */ + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) | 0x20000000); + udelay(10000L); + cpc_writel(&plx_ctl->init_ctrl, + cpc_readl(&plx_ctl->init_ctrl) & ~0x20000000); + +} + +static void show_version(void) +{ + char *rcsvers, *rcsdate, *tmp; + + rcsvers = strchr(rcsid, ' '); + rcsvers++; + tmp = strchr(rcsvers, ' '); + *tmp++ = '\0'; + rcsdate = strchr(tmp, ' '); + rcsdate++; + tmp = strrchr(rcsdate, ' '); + *tmp = '\0'; + pr_info("Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate); +} /* show_version */ + +static const struct net_device_ops cpc_netdev_ops = { + .ndo_open = cpc_open, + .ndo_stop = cpc_close, + .ndo_tx_timeout = cpc_tx_timeout, + .ndo_set_mac_address = NULL, + .ndo_change_mtu = cpc_change_mtu, + .ndo_do_ioctl = cpc_ioctl, + .ndo_validate_addr = eth_validate_addr, +}; + +static void cpc_init_card(pc300_t * card) +{ + int i, devcount = 0; + static int board_nbr = 1; + + /* Enable interrupts on the PCI bridge */ + plx_init(card); + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) | 0x0040); + +#ifdef USE_PCI_CLOCK + /* Set board clock to PCI clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) | 0x00000004UL); + card->hw.clock = PC300_PCI_CLOCK; +#else + /* Set board clock to internal oscillator clock */ + cpc_writel(card->hw.plxbase + card->hw.gpioc_reg, + cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & ~0x00000004UL); + card->hw.clock = PC300_OSC_CLOCK; +#endif + + /* Detect actual on-board RAM size */ + card->hw.ramsize = detect_ram(card); + + /* Set Global SCA-II registers */ + cpc_writeb(card->hw.scabase + PCR, PCR_PR2); + cpc_writeb(card->hw.scabase + BTCR, 0x10); + cpc_writeb(card->hw.scabase + WCRL, 0); + cpc_writeb(card->hw.scabase + DMER, 0x80); + + if (card->hw.type == PC300_TE) { + u8 reg1; + + /* Check CPLD version */ + reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1); + cpc_writeb(card->hw.falcbase + CPLD_REG1, (reg1 + 0x5a)); + if (cpc_readb(card->hw.falcbase + CPLD_REG1) == reg1) { + /* New CPLD */ + card->hw.cpld_id = cpc_readb(card->hw.falcbase + CPLD_ID_REG); + card->hw.cpld_reg1 = CPLD_V2_REG1; + card->hw.cpld_reg2 = CPLD_V2_REG2; + } else { + /* old CPLD */ + card->hw.cpld_id = 0; + card->hw.cpld_reg1 = CPLD_REG1; + card->hw.cpld_reg2 = CPLD_REG2; + cpc_writeb(card->hw.falcbase + CPLD_REG1, reg1); + } + + /* Enable the board's global clock */ + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) | + CPLD_REG1_GLOBAL_CLK); + + } + + for (i = 0; i < card->hw.nchan; i++) { + pc300ch_t *chan = &card->chan[i]; + pc300dev_t *d = &chan->d; + hdlc_device *hdlc; + struct net_device *dev; + + chan->card = card; + chan->channel = i; + chan->conf.phys_settings.clock_rate = 0; + chan->conf.phys_settings.clock_type = CLOCK_EXT; + chan->conf.proto_settings.encoding = ENCODING_NRZ; + chan->conf.proto_settings.parity = PARITY_CRC16_PR1_CCITT; + switch (card->hw.type) { + case PC300_TE: + chan->conf.media = IF_IFACE_T1; + chan->conf.lcode = PC300_LC_B8ZS; + chan->conf.fr_mode = PC300_FR_ESF; + chan->conf.lbo = PC300_LBO_0_DB; + chan->conf.rx_sens = PC300_RX_SENS_SH; + chan->conf.tslot_bitmap = 0xffffffffUL; + break; + + case PC300_X21: + chan->conf.media = IF_IFACE_X21; + break; + + case PC300_RSV: + default: + chan->conf.media = IF_IFACE_V35; + break; + } + chan->conf.proto = IF_PROTO_PPP; + chan->tx_first_bd = 0; + chan->tx_next_bd = 0; + chan->rx_first_bd = 0; + chan->rx_last_bd = N_DMA_RX_BUF - 1; + chan->nfree_tx_bd = N_DMA_TX_BUF; + + d->chan = chan; + d->trace_on = 0; + d->line_on = 0; + d->line_off = 0; + + dev = alloc_hdlcdev(d); + if (dev == NULL) + continue; + + hdlc = dev_to_hdlc(dev); + hdlc->xmit = cpc_queue_xmit; + hdlc->attach = cpc_attach; + d->dev = dev; + dev->mem_start = card->hw.ramphys; + dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1; + dev->irq = card->hw.irq; + dev->tx_queue_len = PC300_TX_QUEUE_LEN; + dev->mtu = PC300_DEF_MTU; + + dev->netdev_ops = &cpc_netdev_ops; + dev->watchdog_timeo = PC300_TX_TIMEOUT; + + if (register_hdlc_device(dev) == 0) { + printk("%s: Cyclades-PC300/", dev->name); + switch (card->hw.type) { + case PC300_TE: + if (card->hw.bus == PC300_PMC) { + printk("TE-M"); + } else { + printk("TE "); + } + break; + + case PC300_X21: + printk("X21 "); + break; + + case PC300_RSV: + default: + printk("RSV "); + break; + } + printk (" #%d, %dKB of RAM at 0x%08x, IRQ%d, channel %d.\n", + board_nbr, card->hw.ramsize / 1024, + card->hw.ramphys, card->hw.irq, i + 1); + devcount++; + } else { + printk ("Dev%d on card(0x%08x): unable to allocate i/f name.\n", + i + 1, card->hw.ramphys); + free_netdev(dev); + continue; + } + } + spin_lock_init(&card->card_lock); + + board_nbr++; +} + +static int __devinit +cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + int err, eeprom_outdated = 0; + u16 device_id; + pc300_t *card; + + if ((err = pci_enable_device(pdev)) < 0) + return err; + + card = kzalloc(sizeof(pc300_t), GFP_KERNEL); + if (card == NULL) { + printk("PC300 found at RAM 0x%016llx, " + "but could not allocate card structure.\n", + (unsigned long long)pci_resource_start(pdev, 3)); + err = -ENOMEM; + goto err_disable_dev; + } + + err = -ENODEV; + + /* read PCI configuration area */ + device_id = ent->device; + card->hw.irq = pdev->irq; + card->hw.iophys = pci_resource_start(pdev, 1); + card->hw.iosize = pci_resource_len(pdev, 1); + card->hw.scaphys = pci_resource_start(pdev, 2); + card->hw.scasize = pci_resource_len(pdev, 2); + card->hw.ramphys = pci_resource_start(pdev, 3); + card->hw.alloc_ramsize = pci_resource_len(pdev, 3); + card->hw.falcphys = pci_resource_start(pdev, 4); + card->hw.falcsize = pci_resource_len(pdev, 4); + card->hw.plxphys = pci_resource_start(pdev, 5); + card->hw.plxsize = pci_resource_len(pdev, 5); + + switch (device_id) { + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_M_1: + card->hw.nchan = 1; + break; + + case PCI_DEVICE_ID_PC300_RX_2: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_2: + default: + card->hw.nchan = PC300_MAXCHAN; + break; + } +#ifdef PC300_DEBUG_PCI + printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", pdev->revision, card->hw.irq); + printk("cpc:found ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.ramphys, card->hw.plxphys, card->hw.scaphys, + card->hw.falcphys); +#endif + /* Although we don't use this I/O region, we should + * request it from the kernel anyway, to avoid problems + * with other drivers accessing it. */ + if (!request_region(card->hw.iophys, card->hw.iosize, "PLX Registers")) { + /* In case we can't allocate it, warn user */ + printk("WARNING: couldn't allocate I/O region for PC300 board " + "at 0x%08x!\n", card->hw.ramphys); + } + + if (card->hw.plxphys) { + pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, card->hw.plxphys); + } else { + eeprom_outdated = 1; + card->hw.plxphys = pci_resource_start(pdev, 0); + card->hw.plxsize = pci_resource_len(pdev, 0); + } + + if (!request_mem_region(card->hw.plxphys, card->hw.plxsize, + "PLX Registers")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate PLX mem region.\n", + card->hw.ramphys); + goto err_release_io; + } + if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize, + "On-board RAM")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate RAM mem region.\n", + card->hw.ramphys); + goto err_release_plx; + } + if (!request_mem_region(card->hw.scaphys, card->hw.scasize, + "SCA-II Registers")) { + printk("PC300 found at RAM 0x%08x, " + "but could not allocate SCA mem region.\n", + card->hw.ramphys); + goto err_release_ram; + } + + card->hw.plxbase = ioremap(card->hw.plxphys, card->hw.plxsize); + card->hw.rambase = ioremap(card->hw.ramphys, card->hw.alloc_ramsize); + card->hw.scabase = ioremap(card->hw.scaphys, card->hw.scasize); + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_1: + case PCI_DEVICE_ID_PC300_TE_M_2: + request_mem_region(card->hw.falcphys, card->hw.falcsize, + "FALC Registers"); + card->hw.falcbase = ioremap(card->hw.falcphys, card->hw.falcsize); + break; + + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.falcbase = NULL; + break; + } + +#ifdef PC300_DEBUG_PCI + printk("cpc: relocate ramaddr=0x%08lx plxaddr=0x%08lx " + "ctladdr=0x%08lx falcaddr=0x%08lx\n", + card->hw.rambase, card->hw.plxbase, card->hw.scabase, + card->hw.falcbase); +#endif + + /* Set PCI drv pointer to the card structure */ + pci_set_drvdata(pdev, card); + + /* Set board type */ + switch (device_id) { + case PCI_DEVICE_ID_PC300_TE_1: + case PCI_DEVICE_ID_PC300_TE_2: + case PCI_DEVICE_ID_PC300_TE_M_1: + case PCI_DEVICE_ID_PC300_TE_M_2: + card->hw.type = PC300_TE; + + if ((device_id == PCI_DEVICE_ID_PC300_TE_M_1) || + (device_id == PCI_DEVICE_ID_PC300_TE_M_2)) { + card->hw.bus = PC300_PMC; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x54; + card->hw.intctl_reg = 0x4c; + } else { + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + } + break; + + case PCI_DEVICE_ID_PC300_RX_1: + case PCI_DEVICE_ID_PC300_RX_2: + default: + card->hw.bus = PC300_PCI; + /* Set PLX register offsets */ + card->hw.gpioc_reg = 0x50; + card->hw.intctl_reg = 0x4c; + + if ((cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & PC300_CTYPE_MASK)) { + card->hw.type = PC300_X21; + } else { + card->hw.type = PC300_RSV; + } + break; + } + + /* Allocate IRQ */ + if (request_irq(card->hw.irq, cpc_intr, IRQF_SHARED, "Cyclades-PC300", card)) { + printk ("PC300 found at RAM 0x%08x, but could not allocate IRQ%d.\n", + card->hw.ramphys, card->hw.irq); + goto err_io_unmap; + } + + cpc_init_card(card); + + if (eeprom_outdated) + printk("WARNING: PC300 with outdated EEPROM.\n"); + return 0; + +err_io_unmap: + iounmap(card->hw.plxbase); + iounmap(card->hw.scabase); + iounmap(card->hw.rambase); + if (card->hw.type == PC300_TE) { + iounmap(card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } + release_mem_region(card->hw.scaphys, card->hw.scasize); +err_release_ram: + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); +err_release_plx: + release_mem_region(card->hw.plxphys, card->hw.plxsize); +err_release_io: + release_region(card->hw.iophys, card->hw.iosize); + kfree(card); +err_disable_dev: + pci_disable_device(pdev); + return err; +} + +static void __devexit cpc_remove_one(struct pci_dev *pdev) +{ + pc300_t *card = pci_get_drvdata(pdev); + + if (card->hw.rambase) { + int i; + + /* Disable interrupts on the PCI bridge */ + cpc_writew(card->hw.plxbase + card->hw.intctl_reg, + cpc_readw(card->hw.plxbase + card->hw.intctl_reg) & ~(0x0040)); + + for (i = 0; i < card->hw.nchan; i++) { + unregister_hdlc_device(card->chan[i].d.dev); + } + iounmap(card->hw.plxbase); + iounmap(card->hw.scabase); + iounmap(card->hw.rambase); + release_mem_region(card->hw.plxphys, card->hw.plxsize); + release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize); + release_mem_region(card->hw.scaphys, card->hw.scasize); + release_region(card->hw.iophys, card->hw.iosize); + if (card->hw.type == PC300_TE) { + iounmap(card->hw.falcbase); + release_mem_region(card->hw.falcphys, card->hw.falcsize); + } + for (i = 0; i < card->hw.nchan; i++) + if (card->chan[i].d.dev) + free_netdev(card->chan[i].d.dev); + if (card->hw.irq) + free_irq(card->hw.irq, card); + kfree(card); + pci_disable_device(pdev); + } +} + +static struct pci_driver cpc_driver = { + .name = "pc300", + .id_table = cpc_pci_dev_id, + .probe = cpc_init_one, + .remove = __devexit_p(cpc_remove_one), +}; + +static int __init cpc_init(void) +{ + show_version(); + return pci_register_driver(&cpc_driver); +} + +static void __exit cpc_cleanup_module(void) +{ + pci_unregister_driver(&cpc_driver); +} + +module_init(cpc_init); +module_exit(cpc_cleanup_module); + +MODULE_DESCRIPTION("Cyclades-PC300 cards driver"); +MODULE_AUTHOR( "Author: Ivan Passos <ivan@cyclades.com>\r\n" + "Maintainer: PC300 Maintainer <pc300@cyclades.com"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/staging/net/pc300_tty.c b/drivers/staging/net/pc300_tty.c new file mode 100644 index 0000000..4709f42 --- /dev/null +++ b/drivers/staging/net/pc300_tty.c @@ -0,0 +1,1079 @@ +/* + * pc300_tty.c Cyclades-PC300(tm) TTY Driver. + * + * Author: Regina Kodato <reginak@cyclades.com> + * + * Copyright: (c) 1999-2002 Cyclades Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * $Log: pc300_tty.c,v $ + * Revision 3.7 2002/03/07 14:17:09 henrique + * License data fixed + * + * Revision 3.6 2001/12/10 12:29:42 regina + * Fix the MLPPP bug + * + * Revision 3.5 2001/10/31 11:20:05 regina + * automatic pppd starts + * + * Revision 3.4 2001/08/06 12:01:51 regina + * problem in DSR_DE bit + * + * Revision 3.3 2001/07/26 22:58:41 regina + * update EDA value + * + * Revision 3.2 2001/07/12 13:11:20 regina + * bug fix - DCD-OFF in pc300 tty driver + * + * DMA transmission bug fix + * + * Revision 3.1 2001/06/22 13:13:02 regina + * MLPPP implementation + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/netdevice.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +#include <linux/if.h> +#include <linux/skbuff.h> +/* TTY includes */ +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/serial.h> + +#include <asm/io.h> +#include <asm/uaccess.h> + +#include "pc300.h" + +/* defines and macros */ +/* TTY Global definitions */ +#define CPC_TTY_NPORTS 8 /* maximum number of the sync tty connections */ +#define CPC_TTY_MAJOR CYCLADES_MAJOR +#define CPC_TTY_MINOR_START 240 /* minor of the first PC300 interface */ + +#define CPC_TTY_MAX_MTU 2000 + +/* tty interface state */ +#define CPC_TTY_ST_IDLE 0 +#define CPC_TTY_ST_INIT 1 /* configured with MLPPP and up */ +#define CPC_TTY_ST_OPEN 2 /* opened by application */ + +#define CPC_TTY_LOCK(card,flags)\ + do {\ + spin_lock_irqsave(&card->card_lock, flags); \ + } while (0) + +#define CPC_TTY_UNLOCK(card,flags) \ + do {\ + spin_unlock_irqrestore(&card->card_lock, flags); \ + } while (0) + +//#define CPC_TTY_DBG(format,a...) printk(format,##a) +#define CPC_TTY_DBG(format,a...) + +/* data structures */ +typedef struct _st_cpc_rx_buf { + struct _st_cpc_rx_buf *next; + int size; + unsigned char data[1]; +} st_cpc_rx_buf; + +struct st_cpc_rx_list { + st_cpc_rx_buf *first; + st_cpc_rx_buf *last; +}; + +typedef struct _st_cpc_tty_area { + int state; /* state of the TTY interface */ + int num_open; + unsigned int tty_minor; /* minor this interface */ + volatile struct st_cpc_rx_list buf_rx; /* ptr. to reception buffer */ + unsigned char* buf_tx; /* ptr. to transmission buffer */ + pc300dev_t* pc300dev; /* ptr. to info struct in PC300 driver */ + unsigned char name[20]; /* interf. name + "-tty" */ + struct tty_struct *tty; + struct work_struct tty_tx_work; /* tx work - tx interrupt */ + struct work_struct tty_rx_work; /* rx work - rx interrupt */ + } st_cpc_tty_area; + +/* TTY data structures */ +static struct tty_driver serial_drv; + +/* local variables */ +static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS]; + +static int cpc_tty_cnt = 0; /* number of intrfaces configured with MLPPP */ +static int cpc_tty_unreg_flag = 0; + +/* TTY functions prototype */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip); +static void cpc_tty_close(struct tty_struct *tty, struct file *flip); +static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count); +static int cpc_tty_write_room(struct tty_struct *tty); +static int cpc_tty_chars_in_buffer(struct tty_struct *tty); +static void cpc_tty_flush_buffer(struct tty_struct *tty); +static void cpc_tty_hangup(struct tty_struct *tty); +static void cpc_tty_rx_work(struct work_struct *work); +static void cpc_tty_tx_work(struct work_struct *work); +static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); +static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); +static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char); + +static int pc300_tiocmset(struct tty_struct *, unsigned int, unsigned int); +static int pc300_tiocmget(struct tty_struct *); + +/* functions called by PC300 driver */ +void cpc_tty_init(pc300dev_t *dev); +void cpc_tty_unregister_service(pc300dev_t *pc300dev); +void cpc_tty_receive(pc300dev_t *pc300dev); +void cpc_tty_trigger_poll(pc300dev_t *pc300dev); + +/* + * PC300 TTY clear "signal" + */ +static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char signal) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Clear signal %x\n", + pc300dev->dev->name, signal); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& signal); + CPC_TTY_UNLOCK(card,flags); +} + +/* + * PC300 TTY set "signal" to ON + */ +static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char signal) +{ + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + unsigned long flags; + + CPC_TTY_DBG("%s-tty: Set signal %x\n", + pc300dev->dev->name, signal); + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CTL,ch), + cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~signal); + CPC_TTY_UNLOCK(card,flags); +} + + +static const struct tty_operations pc300_ops = { + .open = cpc_tty_open, + .close = cpc_tty_close, + .write = cpc_tty_write, + .write_room = cpc_tty_write_room, + .chars_in_buffer = cpc_tty_chars_in_buffer, + .tiocmset = pc300_tiocmset, + .tiocmget = pc300_tiocmget, + .flush_buffer = cpc_tty_flush_buffer, + .hangup = cpc_tty_hangup, +}; + + +/* + * PC300 TTY initialization routine + * + * This routine is called by the PC300 driver during board configuration + * (ioctl=SIOCSP300CONF). At this point the adapter is completely + * initialized. + * o verify kernel version (only 2.4.x) + * o register TTY driver + * o init cpc_tty_area struct + */ +void cpc_tty_init(pc300dev_t *pc300dev) +{ + unsigned long port; + int aux; + st_cpc_tty_area * cpc_tty; + + /* hdlcX - X=interface number */ + port = pc300dev->dev->name[4] - '0'; + if (port >= CPC_TTY_NPORTS) { + printk("%s-tty: invalid interface selected (0-%i): %li", + pc300dev->dev->name, + CPC_TTY_NPORTS-1,port); + return; + } + + if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */ + CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n", + pc300dev->dev->name, + CPC_TTY_MAJOR, CPC_TTY_MINOR_START, + CPC_TTY_MINOR_START+CPC_TTY_NPORTS); + /* initialize tty driver struct */ + memset(&serial_drv,0,sizeof(struct tty_driver)); + serial_drv.magic = TTY_DRIVER_MAGIC; + serial_drv.owner = THIS_MODULE; + serial_drv.driver_name = "pc300_tty"; + serial_drv.name = "ttyCP"; + serial_drv.major = CPC_TTY_MAJOR; + serial_drv.minor_start = CPC_TTY_MINOR_START; + serial_drv.num = CPC_TTY_NPORTS; + serial_drv.type = TTY_DRIVER_TYPE_SERIAL; + serial_drv.subtype = SERIAL_TYPE_NORMAL; + + serial_drv.init_termios = tty_std_termios; + serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; + serial_drv.flags = TTY_DRIVER_REAL_RAW; + + /* interface routines from the upper tty layer to the tty driver */ + tty_set_operations(&serial_drv, &pc300_ops); + + /* register the TTY driver */ + if (tty_register_driver(&serial_drv)) { + printk("%s-tty: Failed to register serial driver! ", + pc300dev->dev->name); + return; + } + + memset((void *)cpc_tty_area, 0, + sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS); + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state != CPC_TTY_ST_IDLE) { + CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n", + pc300dev->dev->name, port); + return; + } + + cpc_tty_cnt++; + cpc_tty->state = CPC_TTY_ST_INIT; + cpc_tty->num_open= 0; + cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; + cpc_tty->pc300dev = pc300dev; + + INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work); + INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work); + + cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; + + pc300dev->cpc_tty = (void *)cpc_tty; + + aux = strlen(pc300dev->dev->name); + memcpy(cpc_tty->name, pc300dev->dev->name, aux); + memcpy(&cpc_tty->name[aux], "-tty", 5); + + cpc_open(pc300dev->dev); + cpc_tty_signal_off(pc300dev, CTL_DTR); + + CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n", + cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); + return; +} + +/* + * PC300 TTY OPEN routine + * + * This routine is called by the tty driver to open the interface + * o verify minor + * o allocate buffer to Rx and Tx + */ +static int cpc_tty_open(struct tty_struct *tty, struct file *flip) +{ + int port ; + st_cpc_tty_area *cpc_tty; + + if (!tty) { + return -ENODEV; + } + + port = tty->index; + + if ((port < 0) || (port >= CPC_TTY_NPORTS)){ + CPC_TTY_DBG("pc300_tty: open invalid port %d\n", port); + return -ENODEV; + } + + cpc_tty = &cpc_tty_area[port]; + + if (cpc_tty->state == CPC_TTY_ST_IDLE){ + CPC_TTY_DBG("%s: open - invalid interface, port=%d\n", + cpc_tty->name, tty->index); + return -ENODEV; + } + + if (cpc_tty->num_open == 0) { /* first open of this tty */ + if (!cpc_tty_area[port].buf_tx){ + cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL); + if (!cpc_tty_area[port].buf_tx) { + CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name); + return -ENOMEM; + } + } + + if (cpc_tty_area[port].buf_rx.first) { + unsigned char * aux; + while (cpc_tty_area[port].buf_rx.first) { + aux = (unsigned char *)cpc_tty_area[port].buf_rx.first; + cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next; + kfree(aux); + } + cpc_tty_area[port].buf_rx.first = NULL; + cpc_tty_area[port].buf_rx.last = NULL; + } + + cpc_tty_area[port].state = CPC_TTY_ST_OPEN; + cpc_tty_area[port].tty = tty; + tty->driver_data = &cpc_tty_area[port]; + + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); + } + + cpc_tty->num_open++; + + CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name); + + /* avisar driver PC300 */ + return 0; +} + +/* + * PC300 TTY CLOSE routine + * + * This routine is called by the tty driver to close the interface + * o call close channel in PC300 driver (cpc_closech) + * o free Rx and Tx buffers + */ + +static void cpc_tty_close(struct tty_struct *tty, struct file *flip) +{ + st_cpc_tty_area *cpc_tty; + unsigned long flags; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlx-tty: no TTY in close\n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + if (!cpc_tty->num_open) { + CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name); + return; + } + + if (--cpc_tty->num_open > 0) { + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + return; + } + + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); + + CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags); /* lock irq */ + cpc_tty->tty = NULL; + cpc_tty->state = CPC_TTY_ST_INIT; + CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ + + if (cpc_tty->buf_rx.first) { + unsigned char * aux; + while (cpc_tty->buf_rx.first) { + aux = (unsigned char *)cpc_tty->buf_rx.first; + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree(aux); + } + cpc_tty->buf_rx.first = NULL; + cpc_tty->buf_rx.last = NULL; + } + + kfree(cpc_tty->buf_tx); + cpc_tty->buf_tx = NULL; + + CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name); + + if (!serial_drv.refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + return; +} + +/* + * PC300 TTY WRITE routine + * + * This routine is called by the tty driver to write a series of characters + * to the tty device. The characters may come from user or kernel space. + * o verify the DCD signal + * o send characters to board and start the transmission + */ +static int cpc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan; + pc300_t *card; + int ch; + unsigned long flags; + struct net_device_stats *stats; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY in write\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name); + return -ENODEV; + } + + if (count > CPC_TTY_MAX_MTU) { + CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name); + return -EINVAL; /* frame too big */ + } + + CPC_TTY_DBG("%s: cpc_tty_write data len=%i\n",cpc_tty->name,count); + + pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; + stats = &cpc_tty->pc300dev->dev->stats; + card = (pc300_t *) pc300chan->card; + ch = pc300chan->channel; + + /* verify DCD signal*/ + if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { + /* DCD is OFF */ + CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name); + stats->tx_errors++; + stats->tx_carrier_errors++; + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & + ~(CPLD_REG2_FALC_LED1 << (2 *ch))); + } + + CPC_TTY_UNLOCK(card, flags); + + return -EINVAL; + } + + if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { + /* failed to send */ + CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name); + return 0; + } + return count; +} + +/* + * PC300 TTY Write Room routine + * + * This routine returns the numbers of characteres the tty driver will accept + * for queuing to be written. + * o return MTU + */ +static int cpc_tty_write_room(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + CPC_TTY_DBG("%s: write room\n",cpc_tty->name); + + return CPC_TTY_MAX_MTU; +} + +/* + * PC300 TTY chars in buffer routine + * + * This routine returns the chars number in the transmission buffer + * o returns 0 + */ +static int cpc_tty_chars_in_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return -ENODEV; + } + + return 0; +} + +static int pc300_tiocmset(struct tty_struct *tty, + unsigned int set, unsigned int clear) +{ + st_cpc_tty_area *cpc_tty; + + CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear); + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); + return -ENODEV; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if (set & TIOCM_RTS) + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_RTS); + if (set & TIOCM_DTR) + cpc_tty_signal_on(cpc_tty->pc300dev, CTL_DTR); + + if (clear & TIOCM_RTS) + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_RTS); + if (clear & TIOCM_DTR) + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); + + return 0; +} + +static int pc300_tiocmget(struct tty_struct *tty) +{ + unsigned int result; + unsigned char status; + unsigned long flags; + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) tty->driver_data; + pc300dev_t *pc300dev = cpc_tty->pc300dev; + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *) pc300chan->card; + int ch = pc300chan->channel; + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + CPC_TTY_DBG("%s-tty: tiocmget\n", + ((struct net_device*)(pc300dev->hdlc))->name); + + CPC_TTY_LOCK(card, flags); + status = cpc_readb(card->hw.scabase+M_REG(CTL,ch)); + CPC_TTY_UNLOCK(card,flags); + + result = ((status & CTL_DTR) ? TIOCM_DTR : 0) | + ((status & CTL_RTS) ? TIOCM_RTS : 0); + + return result; +} + +/* + * PC300 TTY Flush Buffer routine + * + * This routine resets the transmission buffer + */ +static void cpc_tty_flush_buffer(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n"); + return; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return; + } + + CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name); + + tty_wakeup(tty); + return; +} + +/* + * PC300 TTY Hangup routine + * + * This routine is called by the tty driver to hangup the interface + * o clear DTR signal + */ + +static void cpc_tty_hangup(struct tty_struct *tty) +{ + st_cpc_tty_area *cpc_tty; + int res; + + if (!tty || !tty->driver_data ) { + CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n"); + return ; + } + + cpc_tty = (st_cpc_tty_area *) tty->driver_data; + + if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { + CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name); + return ; + } + if (!serial_drv.refcount && cpc_tty_unreg_flag) { + cpc_tty_unreg_flag = 0; + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + cpc_tty_signal_off(cpc_tty->pc300dev, CTL_DTR); +} + +/* + * PC300 TTY RX work routine + * This routine treats RX work + * o verify read buffer + * o call the line disc. read + * o free memory + */ +static void cpc_tty_rx_work(struct work_struct *work) +{ + st_cpc_tty_area *cpc_tty; + unsigned long port; + int i, j; + volatile st_cpc_rx_buf *buf; + char flags=0,flg_rx=1; + struct tty_ldisc *ld; + + if (cpc_tty_cnt == 0) return; + + for (i=0; (i < 4) && flg_rx ; i++) { + flg_rx = 0; + + cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work); + port = cpc_tty - cpc_tty_area; + + for (j=0; j < CPC_TTY_NPORTS; j++) { + cpc_tty = &cpc_tty_area[port]; + + if ((buf=cpc_tty->buf_rx.first) != NULL) { + if (cpc_tty->tty) { + ld = tty_ldisc_ref(cpc_tty->tty); + if (ld) { + if (ld->ops->receive_buf) { + CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); + ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size); + } + tty_ldisc_deref(ld); + } + } + cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next; + kfree((void *)buf); + buf = cpc_tty->buf_rx.first; + flg_rx = 1; + } + if (++port == CPC_TTY_NPORTS) port = 0; + } + } +} + +/* + * PC300 TTY RX work routine + * + * This routine treats RX interrupt. + * o read all frames in card + * o verify the frame size + * o read the frame in rx buffer + */ +static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan) +{ + volatile pcsca_bd_t __iomem * ptdescr; + volatile unsigned char status; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + + /* dma buf read */ + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { + status = cpc_readb(&ptdescr->status); + cpc_writeb(&ptdescr->status, 0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; /* end of message */ + } + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + cpc_readl(&ptdescr->next)); + } +} + +void cpc_tty_receive(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; + pc300_t *card = (pc300_t *)pc300chan->card; + int ch = pc300chan->channel; + volatile pcsca_bd_t __iomem * ptdescr; + struct net_device_stats *stats = &pc300dev->dev->stats; + int rx_len, rx_aux; + volatile unsigned char status; + unsigned short first_bd = pc300chan->rx_first_bd; + st_cpc_rx_buf *new = NULL; + unsigned char dsr_rx; + + if (pc300dev->cpc_tty == NULL) { + return; + } + + dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch)); + + cpc_tty = pc300dev->cpc_tty; + + while (1) { + rx_len = 0; + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd)); + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_len += cpc_readw(&ptdescr->len); + first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1); + if (status & DST_EOM) { + break; + } + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase+cpc_readl(&ptdescr->next)); + } + + if (!rx_len) { + if (dsr_rx & DSR_BOF) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + kfree(new); + return; + } + + if (rx_len > CPC_TTY_MAX_MTU) { + /* Free RX descriptors */ + CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name); + stats->rx_errors++; + stats->rx_frame_errors++; + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC); + if (!new) { + cpc_tty_rx_disc_frame(pc300chan); + continue; + } + + /* dma buf read */ + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + RX_BD_ADDR(ch, pc300chan->rx_first_bd)); + + rx_len = 0; /* counter frame size */ + + while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) { + rx_aux = cpc_readw(&ptdescr->len); + if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) + || (rx_aux > BD_DEF_LEN)) { + CPC_TTY_DBG("%s: reception error\n", cpc_tty->name); + stats->rx_errors++; + if (status & DST_OVR) { + stats->rx_fifo_errors++; + } + if (status & DST_CRC) { + stats->rx_crc_errors++; + } + if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) || + (rx_aux > BD_DEF_LEN)) { + stats->rx_frame_errors++; + } + /* discard remainig descriptors used by the bad frame */ + CPC_TTY_DBG("%s: reception error - discard descriptors", + cpc_tty->name); + cpc_tty_rx_disc_frame(pc300chan); + rx_len = 0; + kfree(new); + new = NULL; + break; /* read next frame - while(1) */ + } + + if (cpc_tty->state != CPC_TTY_ST_OPEN) { + /* Free RX descriptors */ + cpc_tty_rx_disc_frame(pc300chan); + stats->rx_dropped++; + rx_len = 0; + kfree(new); + new = NULL; + break; /* read next frame - while(1) */ + } + + /* read the segment of the frame */ + if (rx_aux != 0) { + memcpy_fromio((new->data + rx_len), + (void __iomem *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), rx_aux); + rx_len += rx_aux; + } + cpc_writeb(&ptdescr->status,0); + cpc_writeb(&ptdescr->len, 0); + pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & + (N_DMA_RX_BUF -1); + if (status & DST_EOM)break; + + ptdescr = (pcsca_bd_t __iomem *) (card->hw.rambase + + cpc_readl(&ptdescr->next)); + } + /* update pointer */ + pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & + (N_DMA_RX_BUF - 1) ; + if (!(dsr_rx & DSR_BOF)) { + /* update EDA */ + cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), + RX_BD_ADDR(ch, pc300chan->rx_last_bd)); + } + if (rx_len != 0) { + stats->rx_bytes += rx_len; + + if (pc300dev->trace_on) { + cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); + } + new->size = rx_len; + new->next = NULL; + if (cpc_tty->buf_rx.first == NULL) { + cpc_tty->buf_rx.first = new; + cpc_tty->buf_rx.last = new; + } else { + cpc_tty->buf_rx.last->next = new; + cpc_tty->buf_rx.last = new; + } + schedule_work(&(cpc_tty->tty_rx_work)); + stats->rx_packets++; + } + } +} + +/* + * PC300 TTY TX work routine + * + * This routine treats TX interrupt. + * o if need call line discipline wakeup + * o call wake_up_interruptible + */ +static void cpc_tty_tx_work(struct work_struct *work) +{ + st_cpc_tty_area *cpc_tty = + container_of(work, st_cpc_tty_area, tty_tx_work); + struct tty_struct *tty; + + CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); + + if ((tty = cpc_tty->tty) == NULL) { + CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name); + return; + } + tty_wakeup(tty); +} + +/* + * PC300 TTY send to card routine + * + * This routine send data to card. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ +static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len) +{ + pc300ch_t *chan = (pc300ch_t *)dev->chan; + pc300_t *card = (pc300_t *)chan->card; + int ch = chan->channel; + struct net_device_stats *stats = &dev->dev->stats; + unsigned long flags; + volatile pcsca_bd_t __iomem *ptdescr; + int i, nchar; + int tosend = len; + int nbuf = ((len - 1)/BD_DEF_LEN) + 1; + unsigned char *pdata=buf; + + CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", + (st_cpc_tty_area *)dev->cpc_tty->name,len); + + if (nbuf >= card->chan[ch].nfree_tx_bd) { + return 1; + } + + /* write buffer to DMA buffers */ + CPC_TTY_DBG("%s: call dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + for (i = 0 ; i < nbuf ; i++) { + ptdescr = (pcsca_bd_t __iomem *)(card->hw.rambase + + TX_BD_ADDR(ch, card->chan[ch].tx_next_bd)); + nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN; + if (cpc_readb(&ptdescr->status) & DST_OSB) { + memcpy_toio((void __iomem *)(card->hw.rambase + + cpc_readl(&ptdescr->ptbuf)), + &pdata[len - tosend], + nchar); + card->chan[ch].nfree_tx_bd--; + if ((i + 1) == nbuf) { + /* This must be the last BD to be used */ + cpc_writeb(&ptdescr->status, DST_EOM); + } else { + cpc_writeb(&ptdescr->status, 0); + } + cpc_writew(&ptdescr->len, nchar); + } else { + CPC_TTY_DBG("%s: error in dma_buf_write\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + stats->tx_dropped++; + return 1; + } + tosend -= nchar; + card->chan[ch].tx_next_bd = + (card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1); + } + + if (dev->trace_on) { + cpc_tty_trace(dev, buf, len,'T'); + } + + /* start transmission */ + CPC_TTY_DBG("%s: start transmission\n", + (st_cpc_tty_area *)dev->cpc_tty->name); + + CPC_TTY_LOCK(card, flags); + cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), + TX_BD_ADDR(ch, chan->tx_next_bd)); + cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); + cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); + + if (card->hw.type == PC300_TE) { + cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, + cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) | + (CPLD_REG2_FALC_LED1 << (2 * ch))); + } + CPC_TTY_UNLOCK(card, flags); + return 0; +} + +/* + * PC300 TTY trace routine + * + * This routine send trace of connection to application. + * o clear descriptors + * o write data to DMA buffers + * o start the transmission + */ + +static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(10 + len)) == NULL) { + /* out of memory */ + CPC_TTY_DBG("%s: tty_trace - out of memory\n", dev->dev->name); + return; + } + + skb_put (skb, 10 + len); + skb->dev = dev->dev; + skb->protocol = htons(ETH_P_CUST); + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_HOST; + skb->len = 10 + len; + + skb_copy_to_linear_data(skb, dev->dev->name, 5); + skb->data[5] = '['; + skb->data[6] = rxtx; + skb->data[7] = ']'; + skb->data[8] = ':'; + skb->data[9] = ' '; + skb_copy_to_linear_data_offset(skb, 10, buf, len); + netif_rx(skb); +} + +/* + * PC300 TTY unregister service routine + * + * This routine unregister one interface. + */ +void cpc_tty_unregister_service(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty; + ulong flags; + int res; + + if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) { + CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name); + return; + } + CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name); + + if (cpc_tty->pc300dev != pc300dev) { + CPC_TTY_DBG("%s: invalid tty ptr=%s\n", + pc300dev->dev->name, cpc_tty->name); + return; + } + + if (--cpc_tty_cnt == 0) { + if (serial_drv.refcount) { + CPC_TTY_DBG("%s: unregister is not possible, refcount=%d", + cpc_tty->name, serial_drv.refcount); + cpc_tty_cnt++; + cpc_tty_unreg_flag = 1; + return; + } else { + CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name); + if ((res=tty_unregister_driver(&serial_drv))) { + CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n", + cpc_tty->name,res); + } + } + } + CPC_TTY_LOCK(pc300dev->chan->card,flags); + cpc_tty->tty = NULL; + CPC_TTY_UNLOCK(pc300dev->chan->card, flags); + cpc_tty->tty_minor = 0; + cpc_tty->state = CPC_TTY_ST_IDLE; +} + +/* + * PC300 TTY trigger poll routine + * This routine is called by pc300driver to treats Tx interrupt. + */ +void cpc_tty_trigger_poll(pc300dev_t *pc300dev) +{ + st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; + if (!cpc_tty) { + return; + } + schedule_work(&(cpc_tty->tty_tx_work)); +} diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index a4c17b0..ba6ed8f 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -42,7 +42,7 @@ * enum nvec_event_size - The size of an event message * @NVEC_2BYTES: The message has one command byte and one data byte * @NVEC_3BYTES: The message has one command byte and two data bytes - * @NVEC_VAR_SIZE: The message has one command byte, one count byte, and as + * @NVEC_VAR_SIZE: The message has one command byte, one count byte, and has * up to as many bytes as the number in the count byte. The * maximum is 32 * diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index d91751f..34afc16 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -163,7 +163,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) /* * We received a packet with either an alignment error * or a FCS error. This may be signalling that we are - * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK} + * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK] * off. If this is the case we need to parse the * packet to determine if we can remove a non spec * preamble and generate a correct packet. diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 5877b2c..5631dd9 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -62,7 +62,7 @@ * You can define GET_SKBUFF_QOS() to override how the skbuff output * function determines which output queue is used. The default * implementation always uses the base queue for the port. If, for - * example, you wanted to use the skb->priority fieid, define + * example, you wanted to use the skb->priority field, define * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority) */ #ifndef GET_SKBUFF_QOS @@ -165,8 +165,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) #endif /* - * Prefetch the private data structure. It is larger that one - * cache line. + * Prefetch the private data structure. It is larger than the + * one cache line. */ prefetch(priv); @@ -291,8 +291,8 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) * See if we can put this skb in the FPA pool. Any strange * behavior from the Linux networking stack will most likely * be caused by a bug in the following code. If some field is - * in use by the network stack and get carried over when a - * buffer is reused, bad thing may happen. If in doubt and + * in use by the network stack and gets carried over when a + * buffer is reused, bad things may happen. If in doubt and * you dont need the absolute best performance, disable the * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has * shown a 25% increase in performance under some loads. diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h index 144fb99..2da5ce1 100644 --- a/drivers/staging/octeon/ethernet-util.h +++ b/drivers/staging/octeon/ethernet-util.h @@ -38,7 +38,7 @@ static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr) } /** - * INTERFACE - convert IPD port to locgical interface + * INTERFACE - convert IPD port to logical interface * @ipd_port: Port to check * * Returns Logical interface diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 60cba81..18f7a79 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -357,7 +357,7 @@ static void cvm_oct_common_set_multicast_list(struct net_device *dev) /* Force accept multicast packets */ control.s.mcst = 2; else - /* Force reject multicat packets */ + /* Force reject multicast packets */ control.s.mcst = 1; if (dev->flags & IFF_PROMISC) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 3d91993..992275c 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -71,8 +71,8 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) ver = dcon_read(dcon, DCON_REG_ID); if ((ver >> 8) != 0xDC) { - printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x " - "instead.\n", ver); + printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x instead.\n", + ver); rc = -ENXIO; goto err; } @@ -134,10 +134,10 @@ static int dcon_bus_stabilize(struct dcon_priv *dcon, int is_powered_down) power_up: if (is_powered_down) { x = 1; - x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) { - printk(KERN_WARNING "olpc-dcon: unable to force dcon " - "to power up: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to force dcon to power up: %d!\n", + x); return x; } msleep(10); /* we'll be conservative */ @@ -150,11 +150,10 @@ power_up: x = dcon_read(dcon, DCON_REG_ID); } if (x < 0) { - printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's " - "smbus, reasserting power and praying.\n"); + printk(KERN_ERR "olpc-dcon: unable to stabilize dcon's smbus, reasserting power and praying.\n"); BUG_ON(olpc_board_at_least(olpc_board(0xc2))); x = 0; - olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); msleep(100); is_powered_down = 1; goto power_up; /* argh, stupid hardware.. */ @@ -220,10 +219,10 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) if (sleep) { x = 0; - x = olpc_ec_cmd(0x26, (unsigned char *) &x, 1, NULL, 0); + x = olpc_ec_cmd(0x26, (unsigned char *)&x, 1, NULL, 0); if (x) - printk(KERN_WARNING "olpc-dcon: unable to force dcon " - "to power down: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to force dcon to power down: %d!\n", + x); else dcon->asleep = sleep; } else { @@ -232,8 +231,8 @@ static void dcon_sleep(struct dcon_priv *dcon, bool sleep) dcon->disp_mode |= MODE_BL_ENABLE; x = dcon_bus_stabilize(dcon, 1); if (x) - printk(KERN_WARNING "olpc-dcon: unable to reinit dcon" - " hardware: %d!\n", x); + printk(KERN_WARNING "olpc-dcon: unable to reinit dcon hardware: %d!\n", + x); else dcon->asleep = sleep; @@ -304,7 +303,7 @@ static void dcon_source_switch(struct work_struct *work) switch (source) { case DCON_SOURCE_CPU: - printk("dcon_source_switch to CPU\n"); + printk(KERN_INFO "dcon_source_switch to CPU\n"); /* Enable the scanline interrupt bit */ if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode | MODE_SCAN_INT)) @@ -599,7 +598,7 @@ static int dcon_fb_notifier(struct notifier_block *self, struct fb_event *evdata = data; struct dcon_priv *dcon = container_of(self, struct dcon_priv, fbevent_nb); - int *blank = (int *) evdata->data; + int *blank = (int *)evdata->data; if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || dcon->ignore_fb_events) return 0; diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index cb6ce0c..c87fdfa 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -116,7 +116,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_NEGATIVE_EDGE_STS); cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_NEGATIVE_EDGE_STS); - /* FIXME: Clear the posiitive status as well, just to be sure */ + /* FIXME: Clear the positive status as well, just to be sure */ cs5535_gpio_set(OLPC_GPIO_DCON_IRQ, GPIO_POSITIVE_EDGE_STS); cs5535_gpio_set(OLPC_GPIO_DCON_BLANK, GPIO_POSITIVE_EDGE_STS); diff --git a/drivers/staging/omapdrm/Makefile b/drivers/staging/omapdrm/Makefile index d9cdc12..1ca0e00 100644 --- a/drivers/staging/omapdrm/Makefile +++ b/drivers/staging/omapdrm/Makefile @@ -13,6 +13,7 @@ omapdrm-y := omap_drv.o \ omap_fb.o \ omap_fbdev.o \ omap_gem.o \ + omap_gem_dmabuf.o \ omap_dmm_tiler.o \ tcm-sita.o diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 1ecb6a7..9d83060 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -347,7 +347,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, ret = tcm_reserve_2d(containers[fmt], w, h, align, &block->area); if (ret) { kfree(block); - return 0; + return ERR_PTR(-ENOMEM); } /* add to allocation list */ @@ -371,7 +371,7 @@ struct tiler_block *tiler_reserve_1d(size_t size) if (tcm_reserve_1d(containers[TILFMT_PAGE], num_pages, &block->area)) { kfree(block); - return 0; + return ERR_PTR(-ENOMEM); } spin_lock(&omap_dmm->list_lock); diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 620b8d5..0d2acca 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -746,7 +746,7 @@ static const struct file_operations omapdriver_fops = { static struct drm_driver omap_drm_driver = { .driver_features = - DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM, + DRIVER_HAVE_IRQ | DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = dev_load, .unload = dev_unload, .open = dev_open, @@ -766,6 +766,10 @@ static struct drm_driver omap_drm_driver = { .debugfs_init = omap_debugfs_init, .debugfs_cleanup = omap_debugfs_cleanup, #endif + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_export = omap_gem_prime_export, + .gem_prime_import = omap_gem_prime_import, .gem_init_object = omap_gem_init_object, .gem_free_object = omap_gem_free_object, .gem_vm_ops = &omap_gem_vm_ops, diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index b7e0f07..f238d57 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -138,6 +138,8 @@ int omap_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma); +int omap_gem_mmap_obj(struct drm_gem_object *obj, + struct vm_area_struct *vma); int omap_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int omap_gem_op_start(struct drm_gem_object *obj, enum omap_gem_op op); int omap_gem_op_finish(struct drm_gem_object *obj, enum omap_gem_op op); @@ -145,12 +147,24 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op); int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op, void (*fxn)(void *arg), void *arg); int omap_gem_roll(struct drm_gem_object *obj, uint32_t roll); +void omap_gem_cpu_sync(struct drm_gem_object *obj, int pgoff); +void omap_gem_dma_sync(struct drm_gem_object *obj, + enum dma_data_direction dir); int omap_gem_get_paddr(struct drm_gem_object *obj, dma_addr_t *paddr, bool remap); int omap_gem_put_paddr(struct drm_gem_object *obj); +int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, + bool remap); +int omap_gem_put_pages(struct drm_gem_object *obj); +uint32_t omap_gem_flags(struct drm_gem_object *obj); uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj); size_t omap_gem_mmap_size(struct drm_gem_object *obj); +struct dma_buf * omap_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags); +struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev, + struct dma_buf *buffer); + static inline int align_pitch(int pitch, int width, int bpp) { int bytespp = (bpp + 7) / 8; diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index 04b235b..74260f0 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -167,7 +167,7 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, int x, int y, } /* Call for unpin 'a' (if not NULL), and pin 'b' (if not NULL). Although - * buffers to unpin are just just pushed to the unpin fifo so that the + * buffers to unpin are just pushed to the unpin fifo so that the * caller can defer unpin until vblank. * * Note if this fails (ie. something went very wrong!), all buffers are @@ -197,8 +197,11 @@ int omap_framebuffer_replace(struct drm_framebuffer *a, pa->paddr = 0; } - if (pb && !ret) + if (pb && !ret) { ret = omap_gem_get_paddr(pb->bo, &pb->paddr, true); + if (!ret) + omap_gem_dma_sync(pb->bo, DMA_TO_DEVICE); + } } if (ret) { diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 921f058..3a0d035 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -207,13 +207,27 @@ static inline bool is_shmem(struct drm_gem_object *obj) return obj->filp != NULL; } +/** + * shmem buffers that are mapped cached can simulate coherency via using + * page faulting to keep track of dirty pages + */ +static inline bool is_cached_coherent(struct drm_gem_object *obj) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); + return is_shmem(obj) && + ((omap_obj->flags & OMAP_BO_CACHE_MASK) == OMAP_BO_CACHED); +} + static DEFINE_SPINLOCK(sync_lock); /** ensure backing pages are allocated */ static int omap_gem_attach_pages(struct drm_gem_object *obj) { + struct drm_device *dev = obj->dev; struct omap_gem_object *omap_obj = to_omap_bo(obj); struct page **pages; + int i, npages = obj->size >> PAGE_SHIFT; + dma_addr_t *addrs; WARN_ON(omap_obj->pages); @@ -231,16 +245,18 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { - int i, npages = obj->size >> PAGE_SHIFT; - dma_addr_t *addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL); + addrs = kmalloc(npages * sizeof(addrs), GFP_KERNEL); for (i = 0; i < npages; i++) { - addrs[i] = dma_map_page(obj->dev->dev, pages[i], + addrs[i] = dma_map_page(dev->dev, pages[i], 0, PAGE_SIZE, DMA_BIDIRECTIONAL); } - omap_obj->addrs = addrs; + } else { + addrs = kzalloc(npages * sizeof(addrs), GFP_KERNEL); } + omap_obj->addrs = addrs; omap_obj->pages = pages; + return 0; } @@ -258,14 +274,21 @@ static void omap_gem_detach_pages(struct drm_gem_object *obj) dma_unmap_page(obj->dev->dev, omap_obj->addrs[i], PAGE_SIZE, DMA_BIDIRECTIONAL); } - kfree(omap_obj->addrs); - omap_obj->addrs = NULL; } + kfree(omap_obj->addrs); + omap_obj->addrs = NULL; + _drm_gem_put_pages(obj, omap_obj->pages, true, false); omap_obj->pages = NULL; } +/* get buffer flags */ +uint32_t omap_gem_flags(struct drm_gem_object *obj) +{ + return to_omap_bo(obj)->flags; +} + /** get mmap offset */ static uint64_t mmap_offset(struct drm_gem_object *obj) { @@ -330,6 +353,7 @@ static int fault_1d(struct drm_gem_object *obj, vma->vm_start) >> PAGE_SHIFT; if (omap_obj->pages) { + omap_gem_cpu_sync(obj, pgoff); pfn = page_to_pfn(omap_obj->pages[pgoff]); } else { BUG_ON(!(omap_obj->flags & OMAP_BO_DMA)); @@ -504,7 +528,6 @@ fail: /** We override mainly to fix up some of the vm mapping flags.. */ int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma) { - struct omap_gem_object *omap_obj; int ret; ret = drm_gem_mmap(filp, vma); @@ -513,8 +536,13 @@ int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma) return ret; } - /* after drm_gem_mmap(), it is safe to access the obj */ - omap_obj = to_omap_bo(vma->vm_private_data); + return omap_gem_mmap_obj(vma->vm_private_data, vma); +} + +int omap_gem_mmap_obj(struct drm_gem_object *obj, + struct vm_area_struct *vma) +{ + struct omap_gem_object *omap_obj = to_omap_bo(obj); vma->vm_flags &= ~VM_PFNMAP; vma->vm_flags |= VM_MIXEDMAP; @@ -524,12 +552,31 @@ int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma) } else if (omap_obj->flags & OMAP_BO_UNCACHED) { vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags)); } else { + /* + * We do have some private objects, at least for scanout buffers + * on hardware without DMM/TILER. But these are allocated write- + * combine + */ + if (WARN_ON(!obj->filp)) + return -EINVAL; + + /* + * Shunt off cached objs to shmem file so they have their own + * address_space (so unmap_mapping_range does what we want, + * in particular in the case of mmap'd dmabufs) + */ + fput(vma->vm_file); + get_file(obj->filp); + vma->vm_pgoff = 0; + vma->vm_file = obj->filp; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); } - return ret; + return 0; } + /** * omap_gem_dumb_create - create a dumb buffer * @drm_file: our client file @@ -639,6 +686,48 @@ fail: return ret; } +/* Sync the buffer for CPU access.. note pages should already be + * attached, ie. omap_gem_get_pages() + */ +void omap_gem_cpu_sync(struct drm_gem_object *obj, int pgoff) +{ + struct drm_device *dev = obj->dev; + struct omap_gem_object *omap_obj = to_omap_bo(obj); + + if (is_cached_coherent(obj) && omap_obj->addrs[pgoff]) { + dma_unmap_page(dev->dev, omap_obj->addrs[pgoff], + PAGE_SIZE, DMA_BIDIRECTIONAL); + omap_obj->addrs[pgoff] = 0; + } +} + +/* sync the buffer for DMA access */ +void omap_gem_dma_sync(struct drm_gem_object *obj, + enum dma_data_direction dir) +{ + struct drm_device *dev = obj->dev; + struct omap_gem_object *omap_obj = to_omap_bo(obj); + + if (is_cached_coherent(obj)) { + int i, npages = obj->size >> PAGE_SHIFT; + struct page **pages = omap_obj->pages; + bool dirty = false; + + for (i = 0; i < npages; i++) { + if (!omap_obj->addrs[i]) { + omap_obj->addrs[i] = dma_map_page(dev->dev, pages[i], 0, + PAGE_SIZE, DMA_BIDIRECTIONAL); + dirty = true; + } + } + + if (dirty) { + unmap_mapping_range(obj->filp->f_mapping, 0, + omap_gem_mmap_size(obj), 1); + } + } +} + /* Get physical address for DMA.. if 'remap' is true, and the buffer is not * already contiguous, remap it to pin in physically contiguous memory.. (ie. * map in TILER) @@ -703,6 +792,7 @@ int omap_gem_get_paddr(struct drm_gem_object *obj, *paddr = omap_obj->paddr; } else { ret = -EINVAL; + goto fail; } fail: @@ -764,9 +854,27 @@ static int get_pages(struct drm_gem_object *obj, struct page ***pages) return 0; } -int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages) +/* if !remap, and we don't have pages backing, then fail, rather than + * increasing the pin count (which we don't really do yet anyways, + * because we don't support swapping pages back out). And 'remap' + * might not be quite the right name, but I wanted to keep it working + * similarly to omap_gem_get_paddr(). Note though that mutex is not + * aquired if !remap (because this can be called in atomic ctxt), + * but probably omap_gem_get_paddr() should be changed to work in the + * same way. If !remap, a matching omap_gem_put_pages() call is not + * required (and should not be made). + */ +int omap_gem_get_pages(struct drm_gem_object *obj, struct page ***pages, + bool remap) { int ret; + if (!remap) { + struct omap_gem_object *omap_obj = to_omap_bo(obj); + if (!omap_obj->pages) + return -ENOMEM; + *pages = omap_obj->pages; + return 0; + } mutex_lock(&obj->dev->struct_mutex); ret = get_pages(obj, pages); mutex_unlock(&obj->dev->struct_mutex); diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c new file mode 100644 index 0000000..42728e0 --- /dev/null +++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -0,0 +1,220 @@ +/* + * drivers/staging/omapdrm/omap_gem_dmabuf.c + * + * Copyright (C) 2011 Texas Instruments + * Author: Rob Clark <rob.clark@linaro.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "omap_drv.h" + +#include <linux/dma-buf.h> + +static struct sg_table *omap_gem_map_dma_buf( + struct dma_buf_attachment *attachment, + enum dma_data_direction dir) +{ + struct drm_gem_object *obj = attachment->dmabuf->priv; + struct sg_table *sg; + dma_addr_t paddr; + int ret; + + sg = kzalloc(sizeof(*sg), GFP_KERNEL); + if (!sg) + return ERR_PTR(-ENOMEM); + + /* camera, etc, need physically contiguous.. but we need a + * better way to know this.. + */ + ret = omap_gem_get_paddr(obj, &paddr, true); + if (ret) + goto out; + + ret = sg_alloc_table(sg, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_init_table(sg->sgl, 1); + sg_dma_len(sg->sgl) = obj->size; + sg_set_page(sg->sgl, pfn_to_page(PFN_DOWN(paddr)), obj->size, 0); + sg_dma_address(sg->sgl) = paddr; + + /* this should be after _get_paddr() to ensure we have pages attached */ + omap_gem_dma_sync(obj, dir); + +out: + if (ret) + return ERR_PTR(ret); + return sg; +} + +static void omap_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *sg, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = attachment->dmabuf->priv; + omap_gem_put_paddr(obj); + sg_free_table(sg); + kfree(sg); +} + +static void omap_gem_dmabuf_release(struct dma_buf *buffer) +{ + struct drm_gem_object *obj = buffer->priv; + /* release reference that was taken when dmabuf was exported + * in omap_gem_prime_set().. + */ + drm_gem_object_unreference_unlocked(obj); +} + + +static int omap_gem_dmabuf_begin_cpu_access(struct dma_buf *buffer, + size_t start, size_t len, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + if (omap_gem_flags(obj) & OMAP_BO_TILED) { + /* TODO we would need to pin at least part of the buffer to + * get de-tiled view. For now just reject it. + */ + return -ENOMEM; + } + /* make sure we have the pages: */ + return omap_gem_get_pages(obj, &pages, true); +} + +static void omap_gem_dmabuf_end_cpu_access(struct dma_buf *buffer, + size_t start, size_t len, enum dma_data_direction dir) +{ + struct drm_gem_object *obj = buffer->priv; + omap_gem_put_pages(obj); +} + + +static void *omap_gem_dmabuf_kmap_atomic(struct dma_buf *buffer, + unsigned long page_num) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + omap_gem_cpu_sync(obj, page_num); + return kmap_atomic(pages[page_num]); +} + +static void omap_gem_dmabuf_kunmap_atomic(struct dma_buf *buffer, + unsigned long page_num, void *addr) +{ + kunmap_atomic(addr); +} + +static void *omap_gem_dmabuf_kmap(struct dma_buf *buffer, + unsigned long page_num) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + omap_gem_cpu_sync(obj, page_num); + return kmap(pages[page_num]); +} + +static void omap_gem_dmabuf_kunmap(struct dma_buf *buffer, + unsigned long page_num, void *addr) +{ + struct drm_gem_object *obj = buffer->priv; + struct page **pages; + omap_gem_get_pages(obj, &pages, false); + kunmap(pages[page_num]); +} + +/* + * TODO maybe we can split up drm_gem_mmap to avoid duplicating + * some here.. or at least have a drm_dmabuf_mmap helper. + */ +static int omap_gem_dmabuf_mmap(struct dma_buf *buffer, + struct vm_area_struct *vma) +{ + struct drm_gem_object *obj = buffer->priv; + int ret = 0; + + if (WARN_ON(!obj->filp)) + return -EINVAL; + + /* Check for valid size. */ + if (omap_gem_mmap_size(obj) < vma->vm_end - vma->vm_start) { + ret = -EINVAL; + goto out_unlock; + } + + if (!obj->dev->driver->gem_vm_ops) { + ret = -EINVAL; + goto out_unlock; + } + + vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; + vma->vm_ops = obj->dev->driver->gem_vm_ops; + vma->vm_private_data = obj; + vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); + + /* Take a ref for this mapping of the object, so that the fault + * handler can dereference the mmap offset's pointer to the object. + * This reference is cleaned up by the corresponding vm_close + * (which should happen whether the vma was created by this call, or + * by a vm_open due to mremap or partial unmap or whatever). + */ + vma->vm_ops->open(vma); + +out_unlock: + + return omap_gem_mmap_obj(obj, vma); +} + +struct dma_buf_ops omap_dmabuf_ops = { + .map_dma_buf = omap_gem_map_dma_buf, + .unmap_dma_buf = omap_gem_unmap_dma_buf, + .release = omap_gem_dmabuf_release, + .begin_cpu_access = omap_gem_dmabuf_begin_cpu_access, + .end_cpu_access = omap_gem_dmabuf_end_cpu_access, + .kmap_atomic = omap_gem_dmabuf_kmap_atomic, + .kunmap_atomic = omap_gem_dmabuf_kunmap_atomic, + .kmap = omap_gem_dmabuf_kmap, + .kunmap = omap_gem_dmabuf_kunmap, + .mmap = omap_gem_dmabuf_mmap, +}; + +struct dma_buf * omap_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *obj, int flags) +{ + return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600); +} + +struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev, + struct dma_buf *buffer) +{ + struct drm_gem_object *obj; + + /* is this one of own objects? */ + if (buffer->ops == &omap_dmabuf_ops) { + obj = buffer->priv; + /* is it from our device? */ + if (obj->dev == dev) { + drm_gem_object_reference(obj); + return obj; + } + } + + /* + * TODO add support for importing buffers from other devices.. + * for now we don't need this but would be nice to add eventually + */ + return ERR_PTR(-EINVAL); +} diff --git a/drivers/staging/omapdrm/tcm-sita.c b/drivers/staging/omapdrm/tcm-sita.c index 10d5ac3..efb6095 100644 --- a/drivers/staging/omapdrm/tcm-sita.c +++ b/drivers/staging/omapdrm/tcm-sita.c @@ -200,7 +200,7 @@ static s32 sita_reserve_1d(struct tcm *tcm, u32 num_slots, * * @param w width * @param h height - * @param area pointer to the area that will be populated with the reesrved + * @param area pointer to the area that will be populated with the reserved * area * * @return 0 on success, non-0 error value on failure. diff --git a/drivers/staging/ozwpan/README b/drivers/staging/ozwpan/README index bb1a69b..7c055ec 100644 --- a/drivers/staging/ozwpan/README +++ b/drivers/staging/ozwpan/README @@ -9,7 +9,7 @@ technology. To operate the driver must be bound to a suitable network interface. This can be done when the module is loaded (specifying the name of the network interface -as a paramter - e.g. 'insmod ozwpan g_net_dev=go0') or can be bound after +as a parameter - e.g. 'insmod ozwpan g_net_dev=go0') or can be bound after loading using an ioctl call. See the ozappif.h file and the ioctls OZ_IOCTL_ADD_BINDING and OZ_IOCTL_REMOVE_BINDING. diff --git a/drivers/staging/ozwpan/ozappif.h b/drivers/staging/ozwpan/ozappif.h index af02732..1b59b07 100644 --- a/drivers/staging/ozwpan/ozappif.h +++ b/drivers/staging/ozwpan/ozappif.h @@ -11,13 +11,13 @@ #define OZ_IOCTL_MAGIC 0xf4 struct oz_mac_addr { - unsigned char a[6]; + __u8 a[6]; }; #define OZ_MAX_PDS 8 struct oz_pd_list { - int count; + __u32 count; struct oz_mac_addr addr[OZ_MAX_PDS]; }; @@ -27,18 +27,10 @@ struct oz_binding_info { char name[OZ_MAX_BINDING_LEN]; }; -struct oz_test { - int action; -}; - #define OZ_IOCTL_GET_PD_LIST _IOR(OZ_IOCTL_MAGIC, 0, struct oz_pd_list) #define OZ_IOCTL_SET_ACTIVE_PD _IOW(OZ_IOCTL_MAGIC, 1, struct oz_mac_addr) #define OZ_IOCTL_GET_ACTIVE_PD _IOR(OZ_IOCTL_MAGIC, 2, struct oz_mac_addr) -#define OZ_IOCTL_CLEAR_EVENTS _IO(OZ_IOCTL_MAGIC, 3) -#define OZ_IOCTL_GET_EVENTS _IOR(OZ_IOCTL_MAGIC, 4, struct oz_evtlist) #define OZ_IOCTL_ADD_BINDING _IOW(OZ_IOCTL_MAGIC, 5, struct oz_binding_info) -#define OZ_IOCTL_TEST _IOWR(OZ_IOCTL_MAGIC, 6, struct oz_test) -#define OZ_IOCTL_SET_EVENT_MASK _IOW(OZ_IOCTL_MAGIC, 7, unsigned long) #define OZ_IOCTL_REMOVE_BINDING _IOW(OZ_IOCTL_MAGIC, 8, struct oz_binding_info) #define OZ_IOCTL_MAX 9 diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 1c380d6..27325f7 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -41,9 +41,6 @@ struct oz_serial_ctx { }; /*------------------------------------------------------------------------------ */ -int g_taction; -/*------------------------------------------------------------------------------ - */ static struct oz_cdev g_cdev; /*------------------------------------------------------------------------------ * Context: process and softirq @@ -276,20 +273,6 @@ long oz_cdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -EFAULT; } break; -#ifdef WANT_EVENT_TRACE - case OZ_IOCTL_CLEAR_EVENTS: - oz_events_clear(); - break; - case OZ_IOCTL_GET_EVENTS: - rc = oz_events_copy((void __user *)arg); - break; - case OZ_IOCTL_SET_EVENT_MASK: - if (copy_from_user(&g_evt_mask, (void __user *)arg, - sizeof(unsigned long))) { - return -EFAULT; - } - break; -#endif /* WANT_EVENT_TRACE */ case OZ_IOCTL_ADD_BINDING: case OZ_IOCTL_REMOVE_BINDING: { struct oz_binding_info b; diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c index 73703d3..7f66b4f 100644 --- a/drivers/staging/ozwpan/ozevent.c +++ b/drivers/staging/ozwpan/ozevent.c @@ -5,29 +5,46 @@ */ #include "ozconfig.h" #ifdef WANT_EVENT_TRACE +#include <linux/module.h> +#include <linux/debugfs.h> #include <linux/jiffies.h> #include <linux/uaccess.h> #include "oztrace.h" #include "ozevent.h" +#include "ozappif.h" /*------------------------------------------------------------------------------ + * Although the event mask is logically part of the oz_evtdev structure, it is + * needed outside of this file so define it seperately to avoid the need to + * export definition of struct oz_evtdev. */ -unsigned long g_evt_mask = 0xffffffff; +u32 g_evt_mask; /*------------------------------------------------------------------------------ */ #define OZ_MAX_EVTS 2048 /* Must be power of 2 */ -DEFINE_SPINLOCK(g_eventlock); -static int g_evt_in; -static int g_evt_out; -static int g_missed_events; -static struct oz_event g_events[OZ_MAX_EVTS]; +struct oz_evtdev { + struct dentry *root_dir; + int evt_in; + int evt_out; + int missed_events; + int present; + atomic_t users; + spinlock_t lock; + struct oz_event evts[OZ_MAX_EVTS]; +}; + +static struct oz_evtdev g_evtdev; + /*------------------------------------------------------------------------------ * Context: process */ void oz_event_init(void) { + /* Because g_evtdev is static external all fields initally zero so no + * need to reinitialised those. + */ oz_trace("Event tracing initialized\n"); - g_evt_in = g_evt_out = 0; - g_missed_events = 0; + spin_lock_init(&g_evtdev.lock); + atomic_set(&g_evtdev.users, 0); } /*------------------------------------------------------------------------------ * Context: process @@ -43,74 +60,136 @@ void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4) { unsigned long irqstate; int ix; - spin_lock_irqsave(&g_eventlock, irqstate); - ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1); - if (ix != g_evt_out) { - struct oz_event *e = &g_events[g_evt_in]; + spin_lock_irqsave(&g_evtdev.lock, irqstate); + ix = (g_evtdev.evt_in + 1) & (OZ_MAX_EVTS - 1); + if (ix != g_evtdev.evt_out) { + struct oz_event *e = &g_evtdev.evts[g_evtdev.evt_in]; e->jiffies = jiffies; e->evt = evt; e->ctx1 = ctx1; e->ctx2 = ctx2; - e->ctx3 = ctx3; + e->ctx3 = (__u32)(unsigned long)ctx3; e->ctx4 = ctx4; - g_evt_in = ix; + g_evtdev.evt_in = ix; } else { - g_missed_events++; + g_evtdev.missed_events++; } - spin_unlock_irqrestore(&g_eventlock, irqstate); + spin_unlock_irqrestore(&g_evtdev.lock, irqstate); } /*------------------------------------------------------------------------------ * Context: process */ -int oz_events_copy(struct oz_evtlist __user *lst) +static void oz_events_clear(struct oz_evtdev *dev) { - int first; - int ix; - struct hdr { - int count; - int missed; - } hdr; - ix = g_evt_out; - hdr.count = g_evt_in - ix; - if (hdr.count < 0) - hdr.count += OZ_MAX_EVTS; - if (hdr.count > OZ_EVT_LIST_SZ) - hdr.count = OZ_EVT_LIST_SZ; - hdr.missed = g_missed_events; - g_missed_events = 0; - if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr))) - return -EFAULT; - first = OZ_MAX_EVTS - ix; - if (first > hdr.count) - first = hdr.count; - if (first) { - int sz = first*sizeof(struct oz_event); - void __user *p = (void __user *)lst->evts; - if (copy_to_user(p, &g_events[ix], sz)) - return -EFAULT; - if (hdr.count > first) { - p = (void __user *)&lst->evts[first]; - sz = (hdr.count-first)*sizeof(struct oz_event); - if (copy_to_user(p, g_events, sz)) - return -EFAULT; - } + unsigned long irqstate; + oz_trace("Clearing events\n"); + spin_lock_irqsave(&dev->lock, irqstate); + dev->evt_in = dev->evt_out = 0; + dev->missed_events = 0; + spin_unlock_irqrestore(&dev->lock, irqstate); +} +#ifdef CONFIG_DEBUG_FS +/*------------------------------------------------------------------------------ + * Context: process + */ +int oz_events_open(struct inode *inode, struct file *filp) +{ + oz_trace("oz_evt_open()\n"); + oz_trace("Open flags: 0x%x\n", filp->f_flags); + if (atomic_add_return(1, &g_evtdev.users) == 1) { + oz_events_clear(&g_evtdev); + return nonseekable_open(inode, filp); + } else { + atomic_dec(&g_evtdev.users); + return -EBUSY; } - ix += hdr.count; - if (ix >= OZ_MAX_EVTS) - ix -= OZ_MAX_EVTS; - g_evt_out = ix; +} +/*------------------------------------------------------------------------------ + * Context: process + */ +int oz_events_release(struct inode *inode, struct file *filp) +{ + oz_events_clear(&g_evtdev); + atomic_dec(&g_evtdev.users); + g_evt_mask = 0; + oz_trace("oz_evt_release()\n"); return 0; } /*------------------------------------------------------------------------------ * Context: process */ -void oz_events_clear(void) +ssize_t oz_events_read(struct file *filp, char __user *buf, size_t count, + loff_t *fpos) { - unsigned long irqstate; - spin_lock_irqsave(&g_eventlock, irqstate); - g_evt_in = g_evt_out = 0; - g_missed_events = 0; - spin_unlock_irqrestore(&g_eventlock, irqstate); + struct oz_evtdev *dev = &g_evtdev; + int rc = 0; + int nb_evts = count / sizeof(struct oz_event); + int n; + int sz; + + n = dev->evt_in - dev->evt_out; + if (n < 0) + n += OZ_MAX_EVTS; + if (nb_evts > n) + nb_evts = n; + if (nb_evts == 0) + goto out; + n = OZ_MAX_EVTS - dev->evt_out; + if (n > nb_evts) + n = nb_evts; + sz = n * sizeof(struct oz_event); + if (copy_to_user(buf, &dev->evts[dev->evt_out], sz)) { + rc = -EFAULT; + goto out; + } + if (n == nb_evts) + goto out2; + n = nb_evts - n; + if (copy_to_user(buf + sz, dev->evts, n * sizeof(struct oz_event))) { + rc = -EFAULT; + goto out; + } +out2: + dev->evt_out = (dev->evt_out + nb_evts) & (OZ_MAX_EVTS - 1); + rc = nb_evts * sizeof(struct oz_event); +out: + return rc; } -#endif /* WANT_EVENT_TRACE */ +/*------------------------------------------------------------------------------ + */ +const struct file_operations oz_events_fops = { + .owner = THIS_MODULE, + .open = oz_events_open, + .release = oz_events_release, + .read = oz_events_read, +}; +/*------------------------------------------------------------------------------ + * Context: process + */ +void oz_debugfs_init(void) +{ + struct dentry *parent; + parent = debugfs_create_dir("ozwpan", NULL); + if (parent == NULL) { + oz_trace("Failed to create debugfs directory ozmo\n"); + return; + } else { + g_evtdev.root_dir = parent; + if (debugfs_create_file("events", S_IRUSR, parent, NULL, + &oz_events_fops) == NULL) + oz_trace("Failed to create file ozmo/events\n"); + if (debugfs_create_x32("event_mask", S_IRUSR | S_IWUSR, parent, + &g_evt_mask) == NULL) + oz_trace("Failed to create file ozmo/event_mask\n"); + } +} +/*------------------------------------------------------------------------------ + * Context: process + */ +void oz_debugfs_remove(void) +{ + debugfs_remove_recursive(g_evtdev.root_dir); +} +#endif /* CONFIG_DEBUG_FS */ +#endif /* WANT_EVENT_TRACE */ diff --git a/drivers/staging/ozwpan/ozevent.h b/drivers/staging/ozwpan/ozevent.h index f033d01..32f6f98 100644 --- a/drivers/staging/ozwpan/ozevent.h +++ b/drivers/staging/ozwpan/ozevent.h @@ -9,23 +9,24 @@ #include "ozeventdef.h" #ifdef WANT_EVENT_TRACE -extern unsigned long g_evt_mask; +extern u32 g_evt_mask; void oz_event_init(void); void oz_event_term(void); void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4); +void oz_debugfs_init(void); +void oz_debugfs_remove(void); #define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) \ do { \ if ((1<<(__evt)) & g_evt_mask) \ oz_event_log2(__evt, __ctx1, __ctx2, __ctx3, __ctx4); \ } while (0) -int oz_events_copy(struct oz_evtlist __user *lst); -void oz_events_clear(void); + #else #define oz_event_init() #define oz_event_term() #define oz_event_log(__evt, __ctx1, __ctx2, __ctx3, __ctx4) -#define oz_events_copy(__lst) -#define oz_events_clear() +#define oz_debugfs_init() +#define oz_debugfs_remove() #endif /* WANT_EVENT_TRACE */ #endif /* _OZEVENT_H */ diff --git a/drivers/staging/ozwpan/ozeventdef.h b/drivers/staging/ozwpan/ozeventdef.h index a880288..4b93898 100644 --- a/drivers/staging/ozwpan/ozeventdef.h +++ b/drivers/staging/ozwpan/ozeventdef.h @@ -29,19 +29,12 @@ #define OZ_EVT_DEBUG 20 struct oz_event { - unsigned long jiffies; - unsigned char evt; - unsigned char ctx1; - unsigned short ctx2; - void *ctx3; - unsigned ctx4; -}; - -#define OZ_EVT_LIST_SZ 64 -struct oz_evtlist { - int count; - int missed; - struct oz_event evts[OZ_EVT_LIST_SZ]; + __u32 jiffies; + __u8 evt; + __u8 ctx1; + __u16 ctx2; + __u32 ctx3; + __u32 ctx4; }; #endif /* _OZEVENTDEF_H */ diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 750b14e..251f07c 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -1416,7 +1416,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, oz_trace("USB_REQ_SET_CONFIGURATION - req\n"); break; case USB_REQ_GET_CONFIGURATION: - /* We short curcuit this case and reply directly since + /* We short circuit this case and reply directly since * we have the selected configuration number cached. */ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0, @@ -1432,7 +1432,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, } break; case USB_REQ_GET_INTERFACE: - /* We short curcuit this case and reply directly since + /* We short circuit this case and reply directly since * we have the selected interface alternative cached. */ oz_event_log(OZ_EVT_CTRL_LOCAL, setup->bRequest, 0, 0, @@ -1463,7 +1463,7 @@ static void oz_process_ep0_urb(struct oz_hcd *ozhcd, struct urb *urb, rc = -ENOMEM; } else { /* Note: we are queuing the request after we have - * submitted it to be tranmitted. If the request were + * submitted it to be transmitted. If the request were * to complete before we queued it then it would not * be found in the queue. It seems impossible for * this to happen but if it did the request would diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index aaf2ccc..7579645 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -33,6 +33,9 @@ static int __init ozwpan_init(void) oz_protocol_init(g_net_dev); oz_app_enable(OZ_APPID_USB, 1); oz_apps_init(); +#ifdef CONFIG_DEBUG_FS + oz_debugfs_init(); +#endif return 0; } /*------------------------------------------------------------------------------ @@ -44,6 +47,9 @@ static void __exit ozwpan_exit(void) oz_apps_term(); oz_cdev_deregister(); oz_event_term(); +#ifdef CONFIG_DEBUG_FS + oz_debugfs_remove(); +#endif } /*------------------------------------------------------------------------------ */ @@ -53,6 +59,6 @@ module_exit(ozwpan_exit); MODULE_AUTHOR("Chris Kelly"); MODULE_DESCRIPTION("Ozmo Devices USB over WiFi hcd driver"); -MODULE_VERSION("1.0.8"); +MODULE_VERSION("1.0.9"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ozwpan/ozusbsvc.c b/drivers/staging/ozwpan/ozusbsvc.c index 9e74f96..8fa7f25 100644 --- a/drivers/staging/ozwpan/ozusbsvc.c +++ b/drivers/staging/ozwpan/ozusbsvc.c @@ -7,7 +7,7 @@ * The implementation of this service is split into two parts the first of which * is protocol independent and the second contains protocol specific details. * This split is to allow alternative protocols to be defined. - * The implemenation of this service uses ozhcd.c to implement a USB HCD. + * The implementation of this service uses ozhcd.c to implement a USB HCD. * ----------------------------------------------------------------------------- */ #include <linux/init.h> diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 6183573..7365089 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -754,7 +754,7 @@ static void lcd_backlight(int on) if (lcd_bl_pin == PIN_NONE) return; - /* The backlight is activated by seting the AUTOFEED line to +5V */ + /* The backlight is activated by setting the AUTOFEED line to +5V */ spin_lock(&pprt_lock); bits.bl = on; panel_set_bits(); diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig index 4af1f8d..8349887 100644 --- a/drivers/staging/ramster/Kconfig +++ b/drivers/staging/ramster/Kconfig @@ -1,6 +1,6 @@ config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && NET select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c index b9721c1..d0a07d7 100644 --- a/drivers/staging/ramster/cluster/tcp.c +++ b/drivers/staging/ramster/cluster/tcp.c @@ -111,7 +111,7 @@ static struct socket *r2net_listen_sock; * r2net_wq. teardown detaches the callbacks before destroying the workqueue. * quorum work is queued as sock containers are shutdown.. stop_listening * tears down all the node's sock containers, preventing future shutdowns - * and queued quroum work, before canceling delayed quorum work and + * and queued quorum work, before canceling delayed quorum work and * destroying the work queue. */ static struct workqueue_struct *r2net_wq; @@ -660,7 +660,7 @@ out: /* * we register callbacks so we can queue work on events before calling - * the original callbacks. our callbacks our careful to test user_data + * the original callbacks. our callbacks are careful to test user_data * to discover when they've reaced with r2net_unregister_callbacks(). */ static void r2net_register_callbacks(struct sock *sk, diff --git a/drivers/staging/ramster/xvmalloc.c b/drivers/staging/ramster/xvmalloc.c index 93ba8e9..44ceb0b 100644 --- a/drivers/staging/ramster/xvmalloc.c +++ b/drivers/staging/ramster/xvmalloc.c @@ -132,7 +132,7 @@ static u32 find_block(struct xv_pool *pool, u32 size, if (!pool->flbitmap) return 0; - /* Get freelist index correspoding to this size */ + /* Get freelist index corresponding to this size */ slindex = get_index(size); slbitmap = pool->slbitmap[slindex / BITS_PER_LONG]; slbitstart = slindex % BITS_PER_LONG; diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c index 68b2e05..4e7ef0e 100644 --- a/drivers/staging/ramster/zcache-main.c +++ b/drivers/staging/ramster/zcache-main.c @@ -1331,7 +1331,7 @@ static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, * when that limit is reached, further puts will be rejected (until * some pages have been flushed). Note that, due to compression, * this number may exceed 100; it defaults to 75 and we set an - * arbitary limit of 150. A poor choice will almost certainly result + * arbitrary limit of 150. A poor choice will almost certainly result * in OOM's, so this value should only be changed prudently. */ static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, @@ -2004,7 +2004,7 @@ int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj) * Called by the message handler after a (still compressed) page has been * fetched from the remote machine in response to an "is_remote" tmem_get * or persistent tmem_localify. For a tmem_get, "extra" is the address of - * the page that is to be filled to succesfully resolve the tmem_get; for + * the page that is to be filled to successfully resolve the tmem_get; for * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only * in the local zcache). "data" points to "size" bytes of (compressed) data * passed in the message. In the case of a persistent remote get, if @@ -2095,7 +2095,7 @@ out: /* * Called on a remote persistent tmem_get to attempt to preallocate * local storage for the data contained in the remote persistent page. - * If succesfully preallocated, returns the pampd, marked as remote and + * If successfully preallocated, returns the pampd, marked as remote and * in_transit. Else returns NULL. Note that the appropriate tmem data * structure must be locked. */ diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile index 72db504..91d1aa2 100644 --- a/drivers/staging/rtl8187se/Makefile +++ b/drivers/staging/rtl8187se/Makefile @@ -10,7 +10,7 @@ ccflags-y += -DHIGH_POWER ccflags-y += -DSW_DIG ccflags-y += -DRATE_ADAPT -#enable it for legacy power save, disable it for leisure power save +#enable it for legacy power save, disable it for leisure power save ccflags-y += -DENABLE_LPS diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c index 309bb8b..0e93eb0 100644 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.c +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c @@ -55,7 +55,7 @@ Dot11d_Reset(struct ieee80211_device *ieee) // // Description: -// Update country IE from Beacon or Probe Resopnse +// Update country IE from Beacon or Probe Response // and configure PHY for operation in the regulatory domain. // // TODO: diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 40dd715..b94c48b 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -834,7 +834,7 @@ enum ieee80211_state { /* the association procedure is sending AUTH request*/ IEEE80211_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ IEEE80211_ASSOCIATING_AUTHENTICATED, @@ -934,7 +934,7 @@ struct ieee80211_device { * with RX of broad/multicast frames */ /* Fragmentation structures */ - // each streaming contain a entry + /* each stream contains an entry */ struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; unsigned int frag_next_idx[17]; u16 fts; /* Fragmentation Threshold */ @@ -972,7 +972,7 @@ struct ieee80211_device { int rate; /* current rate */ int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features + //FIXME: please callback, see if redundant with softmac_features short active_scan; /* this contains flags for selectively enable softmac support */ @@ -1106,7 +1106,7 @@ struct ieee80211_device { /* used instead of hard_start_xmit (not softmac_hard_start_xmit) * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set * then also management frames are sent via this callback. * This function can't sleep. */ @@ -1124,7 +1124,7 @@ struct ieee80211_device { /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure - * the radio has been swithced before return. + * the radio has been switched before return. */ void (*set_chan)(struct net_device *dev,short ch); @@ -1135,7 +1135,7 @@ struct ieee80211_device { * The syncro version is similar to the start_scan but * does not return until all channels has been scanned. * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode + * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. * the function stop_scan should stop both the syncro and @@ -1196,7 +1196,7 @@ struct ieee80211_device { /* Generate probe requests */ #define IEEE_SOFTMAC_PROBERQ (1<<4) -/* Generate respones to probe requests */ +/* Generate response to probe requests */ #define IEEE_SOFTMAC_PROBERS (1<<5) /* The ieee802.11 stack will manages the netif queue diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 26bacb9..8173240 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -42,7 +42,7 @@ short ieee80211_is_shortslot(const struct ieee80211_network *net) return net->capability & WLAN_CAPABILITY_SHORT_SLOT; } -/* returns the total length needed for pleacing the RATE MFIE +/* returns the total length needed for placing the RATE MFIE * tag and the EXTENDED RATE MFIE tag if needed. * It encludes two bytes per tag for the tag itself and its len */ @@ -60,7 +60,7 @@ unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) return rate_len; } -/* pleace the MFIE rate, tag to the memory (double) poined. +/* place the MFIE rate, tag to the memory (double) poised. * Then it updates the pointer so that * it points after the new MFIE tag added. */ @@ -467,7 +467,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) * So we switch to IEEE80211_LINKED_SCANNING to remember * that we are still logically linked (not interested in * new network events, despite for updating the net list, - * but we are temporarly 'unlinked' as the driver shall + * but we are temporarily 'unlinked' as the driver shall * not filter RX frames and the channel is changing. * So the only situation in witch are interested is to check * if the state become LINKED because of the #1 situation @@ -530,7 +530,7 @@ void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee) * So we switch to IEEE80211_LINKED_SCANNING to remember * that we are still logically linked (not interested in * new network events, despite for updating the net list, - * but we are temporarly 'unlinked' as the driver shall + * but we are temporarily 'unlinked' as the driver shall * not filter RX frames and the channel is changing. * So the only situation in witch are interested is to check * if the state become LINKED because of the #1 situation @@ -1140,7 +1140,7 @@ void ieee80211_associate_abort(struct ieee80211_device *ieee) ieee->associate_seq++; - /* don't scan, and avoid to have the RX path possibily + /* don't scan, and avoid to have the RX path possibly * try again to associate. Even do not react to AUTH or * ASSOC response. Just wait for the retry wq to be scheduled. * Here we will check if there are good nets to associate @@ -1346,14 +1346,14 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee //printk("apset=%d apmatch=%d ssidset=%d ssidbroad=%d ssidmatch=%d\n",apset,apmatch,ssidset,ssidbroad,ssidmatch); if ( /* if the user set the AP check if match. - * if the network does not broadcast essid we check the user supplyed ANY essid + * if the network does not broadcast essid we check the user supplied ANY essid * if the network does broadcast and the user does not set essid it is OK * if the network does broadcast and the user did set essid chech if essid match */ ( apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || /* if the ap is not set, check that the user set the bssid - * and the network does bradcast and that those two bssid matches + * and the network does broadcast and that those two bssid matches */ (!apset && ssidset && ssidbroad && ssidmatch) ){ @@ -1821,7 +1821,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, while (left >= sizeof(struct ieee80211_info_element_hdr)) { if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { - printk(KERN_WARNING "[re]associate reeponse error!"); + printk(KERN_WARNING "[re]associate response error!"); return 1; } switch (info_element->id) { @@ -1905,7 +1905,7 @@ associate_complete: } }else{ ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode); ieee80211_associate_abort(ieee); } @@ -2184,15 +2184,15 @@ void ieee80211_start_ibss_wq(struct work_struct *work) if(ieee->state == IEEE80211_NOLINK) ieee->current_network.channel = 10; - /* if not then the state is not linked. Maybe the user swithced to + /* if not then the state is not linked. Maybe the user switched to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no * time to scan all the chans..) or we have just run up the iface * after setting ad-hoc mode. So we have to give another try.. * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tryed to associate when + * (in bss mode we had to make sure no-one tried to associate when * we had just checked the ieee->state and we was going to start the - * scan) beacause in ibss mode the ieee80211_new_net function, when + * scan) because in ibss mode the ieee80211_new_net function, when * finds a good net, just set the ieee->state to IEEE80211_LINKED, * so, at worst, we waste a bit of time to initiate an unneeded syncro * scan, that will stop at the first round because it sees the state @@ -2342,7 +2342,7 @@ void ieee80211_associate_retry_wq(struct work_struct *work) goto exit; /* until we do not set the state to IEEE80211_NOLINK * there are no possibility to have someone else trying - * to start an association procdure (we get here with + * to start an association procedure (we get here with * ieee->state = IEEE80211_ASSOCIATING). * When we set the state to IEEE80211_NOLINK it is possible * that the RX path run an attempt to associate, but diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index e46ff2f..5d20490 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -362,7 +362,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, ieee80211_stop_protocol(ieee); /* this is just to be sure that the GET wx callback - * has consisten infos. not needed otherwise + * has consistent infos. not needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index 552115c..89ed86e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -328,7 +328,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, //printk(KERN_WARNING "upper layer packet!\n"); spin_lock_irqsave(&ieee->lock, flags); - /* If there is no driver handler to take the TXB, dont' bother + /* If there is no driver handler to take the TXB, don't bother * creating it... */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { @@ -413,10 +413,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, /* Determine fragmentation size based on destination (multicast * and broadcast are not fragmented) */ -// if (is_multicast_ether_addr(dest) || -// is_broadcast_ether_addr(dest)) { - if (is_multicast_ether_addr(header.addr1) || - is_broadcast_ether_addr(header.addr1)) { + if (is_multicast_ether_addr(header.addr1)) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl = QOS_CTL_NOTCONTAIN_ACK; } diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c index ca414a9..c7917b2 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c @@ -363,7 +363,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, (*crypt)->priv); sec.flags |= (1 << key); /* This ensures a key will be activated if no key is - * explicitely set */ + * explicitly set */ if (key == sec.active_key) sec.flags |= SEC_ACTIVE_KEY; ieee->tx_keyidx = key;//by wb 080312 diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index a2c46ae..2682afb 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -11,7 +11,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -514,12 +514,12 @@ typedef struct r8180_priv bool bDefaultAntenna1; u8 SignalStrength; long Stats_SignalStrength; - long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average. + long LastSignalStrengthInPercent; // In percentage, used for smoothing, e.g. Moving Average. u8 SignalQuality; // in 0-100 index. long Stats_SignalQuality; long RecvSignalPower; // in dBm. long Stats_RecvSignalPower; - u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25. + u8 LastRxPktAntenna; // +by amy 080312 Antenna which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25. u32 AdRxOkCnt; long AdRxSignalStrength; u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx). @@ -530,7 +530,7 @@ typedef struct r8180_priv long AdRxSsThreshold; // Signal strength threshold to switch antenna. long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold. bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna. - long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna. + long AdRxSsBeforeSwitched; // Rx signal strength before we switched antenna. struct timer_list SwAntennaDiversityTimer; //by amy for antenna //{by amy 080312 @@ -553,7 +553,7 @@ typedef struct r8180_priv bool bDigMechanism; // TRUE if DIG is enabled, FALSE ow. bool bRegHighPowerMechanism; // For High Power Mechanism. 061010, by rcnjko. u32 FalseAlarmRegValue; - u8 RegDigOfdmFaUpTh; // Upper threhold of OFDM false alarm, which is used in DIG. + u8 RegDigOfdmFaUpTh; // Upper threshold of OFDM false alarm, which is used in DIG. u8 DIG_NumberFallbackVote; u8 DIG_NumberUpgradeVote; // For HW antenna diversity, added by Roger, 2008.01.30. diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 4fe52f6..fd22b75 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1329,7 +1329,7 @@ u16 N_DBPSOfRate(u16 DataRate) } /* - * For Netgear case, they want good-looking singal strength. + * For Netgear case, they want good-looking signal strength. */ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) { @@ -1380,7 +1380,7 @@ long TranslateToDbm8185(u8 SignalStrengthIndex) /* * Perform signal smoothing for dynamic mechanism. - * This is different with PerformSignalSmoothing8185 in smoothing fomula. + * This is different with PerformSignalSmoothing8185 in smoothing formula. * No dramatic adjustion is apply because dynamic mechanism need some degree * of correctness. Ported from 8187B. */ @@ -1535,7 +1535,7 @@ void rtl8180_rx(struct net_device *dev) /* HW is probably passing several buggy frames * without FD or LD flag set. * Throw this garbage away to prevent skb - * memory exausting + * memory exhausting */ if (!priv->rx_skb_complete) dev_kfree_skb_any(priv->rx_skb); @@ -1648,14 +1648,14 @@ void rtl8180_rx(struct net_device *dev) priv->Stats_SignalQuality = (long)(priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6; priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower - 1) / 6; - /* Figure out which antenna that received the lasted packet. */ + /* Figure out which antenna that received the last packet. */ priv->LastRxPktAntenna = Antenna ? 1 : 0; /* 0: aux, 1: main. */ SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); } if (first) { if (!priv->rx_skb_complete) { - /* seems that HW sometimes fails to reiceve and + /* seems that HW sometimes fails to receive and doesn't provide the last descriptor */ dev_kfree_skb_any(priv->rx_skb); priv->stats.rxnolast++; @@ -1672,7 +1672,7 @@ void rtl8180_rx(struct net_device *dev) priv->rx_skb_complete = 0; priv->rx_skb->dev = dev; } else { - /* if we are here we should have already RXed + /* if we are here we should have already RXed * the first frame. * If we get here and the skb is not allocated then * we have just throw out garbage (skb not allocated) @@ -1821,15 +1821,15 @@ rate) { /* * This is a rough attempt to TX a frame * This is called by the ieee 80211 stack to TX management frames. - * If the ring is full packet are dropped (for data frame the queue + * If the ring is full packets are dropped (for data frame the queue * is stopped before this can happen). For this reason it is better * if the descriptors are larger than the largest management frame - * we intend to TX: i'm unsure what the HW does if it will not found + * we intend to TX: i'm unsure what the HW does if it will not find * the last fragment of a frame because it has been dropped... * Since queues for Management and Data frames are different we * might use a different lock than tx_lock (for example mgmt_tx_lock) */ -/* these function may loops if invoked with 0 descriptors or 0 len buffer */ +/* these function may loop if invoked with 0 descriptors or 0 len buffer */ int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -2003,8 +2003,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, } memcpy(&dest, frag_hdr->addr1, ETH_ALEN); - if (is_multicast_ether_addr(dest) || - is_broadcast_ether_addr(dest)) { + if (is_multicast_ether_addr(dest)) { Duration = 0; RtsDur = 0; bRTSEnable = 0; @@ -2378,7 +2377,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 u1bAIFS; u32 u4bAcParam; pAcParam = (PAC_PARAM)(&AcParam); - /* Retrive paramters to udpate. */ + /* Retrieve paramters to update. */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<<AC_PARAM_TXOP_LIMIT_OFFSET)| (((u32)(pAcParam->f.Ecw.f.ECWmax))<<AC_PARAM_ECW_MAX_OFFSET)| @@ -2414,7 +2413,7 @@ void rtl8180_wmm_param_update(struct work_struct *work) u8 u1bAIFS; u32 u4bAcParam; - /* Retrive paramters to udpate. */ + /* Retrieve paramters to update. */ eACI = pAcParam->f.AciAifsn.f.ACI; /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G) ? 9 : 20) + aSifsTime; @@ -2700,7 +2699,7 @@ short rtl8180_init(struct net_device *dev) priv->bTxPowerTrack = false; priv->ThermalMeter = 0; priv->FalseAlarmRegValue = 0; - priv->RegDigOfdmFaUpTh = 0xc; /* Upper threhold of OFDM false alarm, which is used in DIG. */ + priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm, which is used in DIG. */ priv->DIG_NumberFallbackVote = 0; priv->DIG_NumberUpgradeVote = 0; priv->LastSignalStrengthInPercent = 0; @@ -2896,7 +2895,7 @@ short rtl8180_init(struct net_device *dev) priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8; } - /* 3Read crystal calibtration and thermal meter indication on 87SE. */ + /* 3Read crystal calibration and thermal meter indication on 87SE. */ eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16); /* Crystal calibration for Xin and Xout resp. */ @@ -3140,7 +3139,7 @@ void rtl8180_adapter_start(struct net_device *dev) /* * The following is very strange. seems to be that 1 means test mode, - * but we need to acknolwledges the nic when a packet is ready + * but we need to acknowledges the nic when a packet is ready * although we set it to 0 */ @@ -3971,7 +3970,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) } if (inta == 0xffff) { - /* HW disappared */ + /* HW disappeared */ spin_unlock_irqrestore(&priv->irq_th_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c index 4d7a595..b8f2ba0 100644 --- a/drivers/staging/rtl8187se/r8180_dm.c +++ b/drivers/staging/rtl8187se/r8180_dm.c @@ -2,7 +2,7 @@ #include "r8180_hw.h" #include "r8180_93cx6.h" - /* Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise. */ + /* Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */ #define RATE_ADAPTIVE_TIMER_PERIOD 300 bool CheckHighPower(struct net_device *dev) @@ -105,7 +105,7 @@ void rtl8180_tx_pw_wq(struct work_struct *work) /* - * Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise. + * Return TRUE if we shall perform DIG Mechanism, FALSE otherwise. */ bool CheckDig(struct net_device *dev) { @@ -507,7 +507,7 @@ void StaRateAdaptive87SE(struct net_device *dev) * and retry rate. * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated * situation, Initial Gain Update is upon on DIG mechanism except CCK rate. - * (4) Add the mehanism of trying to upgrade tx rate. + * (4) Add the mechanism of trying to upgrade tx rate. * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly. * */ @@ -528,7 +528,7 @@ void StaRateAdaptive87SE(struct net_device *dev) if (priv->bTryuping == true) { /* 2 For Test Upgrading mechanism * Note: - * Sometimes the throughput is upon on the capability bwtween the AP and NIC, + * Sometimes the throughput is upon on the capability between the AP and NIC, * thus the low data rate does not improve the performance. * We randomly upgrade the data rate and check if the retry rate is improved. */ @@ -704,7 +704,7 @@ void StaRateAdaptive87SE(struct net_device *dev) /* * The difference in throughput between 48Mbps and 36Mbps is 8M. - * So, we must be carefully in this rate scale. Isaiah 2008-02-15. + * So, we must be careful in this rate scale. Isaiah 2008-02-15. */ if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) && (priv->FailTxRateCount > 2)) @@ -1009,7 +1009,7 @@ void SwAntennaDiversity(struct net_device *dev) if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod) priv->AdCheckPeriod = priv->AdMaxCheckPeriod; - /* Wrong deceision => switch back. */ + /* Wrong decision => switch back. */ SwitchAntenna(dev); } else { /* Rx Signal Strength is improved. */ @@ -1057,7 +1057,7 @@ void SwAntennaDiversity(struct net_device *dev) } /* * <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna - * didn't changed by HW evaluation. + * didn't change by HW evaluation. * 2008.02.27. * * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 @@ -1098,7 +1098,7 @@ void SwAntennaDiversity(struct net_device *dev) priv->AdAuxAntennaRxOkCnt = 0; } - /* Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise. */ + /* Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */ bool CheckTxPwrTracking(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index ee5b867..d28c1d9 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -190,7 +190,7 @@ static void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch) write_phy_cck(dev, 0x44 + i, power); } - /* FIXME Is this delay really needeed ? */ + /* FIXME Is this delay really needed ? */ force_pci_posting(dev); mdelay(1); @@ -479,7 +479,7 @@ s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode, /* * TRUE if we want to use a default implementation. - * We shall set it to FALSE when we have exact translation formular + * We shall set it to FALSE when we have exact translation formula * for target IC. 070622, by rcnjko. */ if (bUseDefault) { diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 303ec69..46ee6f4 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -13,7 +13,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thanks the Authors of those projects and the Ndiswrapper project Authors. */ @@ -1181,7 +1181,7 @@ static iw_handler r8180_wx_handlers[] = { r8180_wx_set_wap, /* SIOCSIWAP */ r8180_wx_get_wap, /* SIOCGIWAP */ r8180_wx_set_mlme, /* SIOCSIWMLME*/ - dummy, /* SIOCGIWAPLIST -- depricated */ + dummy, /* SIOCGIWAPLIST -- deprecated */ r8180_wx_set_scan, /* SIOCSIWSCAN */ r8180_wx_get_scan, /* SIOCGIWSCAN */ r8180_wx_set_essid, /* SIOCSIWESSID */ @@ -1369,7 +1369,7 @@ static inline int is_same_network(struct ieee80211_network *src, (dst->capability & WLAN_CAPABILITY_BSS))); } -/* WB modefied to show signal to GUI on 18-01-2008 */ +/* WB modified to show signal to GUI on 18-01-2008 */ static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h index 735d03d..4081914 100644 --- a/drivers/staging/rtl8187se/r8180_wx.h +++ b/drivers/staging/rtl8187se/r8180_wx.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thanks the Authors of such projects and the Ndiswrapper project Authors. */ /* this file (will) contains wireless extension handlers*/ diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 4b0b830..9144957 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1,22 +1,22 @@ -/*++ -Copyright (c) Realtek Semiconductor Corp. All rights reserved. - -Module Name: - r8185b_init.c - -Abstract: - Hardware Initialization and Hardware IO for RTL8185B - -Major Change History: - When Who What - ---------- --------------- ------------------------------- - 2006-11-15 Xiong Created - -Notes: - This file is ported from RTL8185B Windows driver. - - ---*/ +/* + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Module Name: + * r8185b_init.c + * + * Abstract: + * Hardware Initialization and Hardware IO for RTL8185B + * + * Major Change History: + * When Who What + * ---------- --------------- ------------------------------- + * 2006-11-15 Xiong Created + * + * Notes: + * This file is ported from RTL8185B Windows driver. + * + * + */ /*--------------------------Include File------------------------------------*/ #include <linux/spinlock.h> @@ -25,155 +25,134 @@ Notes: #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */ #include "r8180_93cx6.h" /* Card EEPROM */ #include "r8180_wx.h" - #include "ieee80211/dot11d.h" - - /* #define CONFIG_RTL8180_IO_MAP */ - #define TC_3W_POLL_MAX_TRY_CNT 5 + static u8 MAC_REG_TABLE[][2] = { - /*PAGA 0: */ - /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */ - /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */ - /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */ - {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42}, - {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03}, - {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03}, - {0x94, 0x0F}, {0x95, 0x32}, - {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00}, - {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32}, - {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4}, - {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00}, - {0xff, 0x00}, - - /*PAGE 1: */ - /* For Flextronics system Logo PCIHCT failure: */ - /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */ - {0x5e, 0x01}, - {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24}, - {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF}, - {0x82, 0xFF}, {0x83, 0x03}, - {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */ - {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},/* lzm add 080826 */ - {0xe2, 0x00}, - - - /* PAGE 2: */ - {0x5e, 0x02}, - {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5}, - {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff}, - {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08}, - {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f}, - {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f}, - {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff}, - {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00}, - - /* PAGA 0: */ - {0x5e, 0x00}, {0x9f, 0x03} - }; - - -static u8 ZEBRA_AGC[] = { - 0, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, - 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, - 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, - 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, - 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, - 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F - }; - -static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { - 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, - 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, - 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, - 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, - 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 + /*PAGA 0: */ + /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */ + /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */ + /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */ + {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42}, + {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03}, + {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03}, + {0x94, 0x0F}, {0x95, 0x32}, + {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00}, + {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32}, + {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4}, + {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00}, + {0xff, 0x00}, + + /*PAGE 1: */ + /* For Flextronics system Logo PCIHCT failure: */ + /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */ + {0x5e, 0x01}, + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24}, + {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF}, + {0x82, 0xFF}, {0x83, 0x03}, + {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */ + {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22}, /* lzm add 080826 */ + {0xe2, 0x00}, + + + /* PAGE 2: */ + {0x5e, 0x02}, + {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5}, + {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff}, + {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08}, + {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f}, + {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f}, + {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff}, + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00}, + + /* PAGA 0: */ + {0x5e, 0x00}, {0x9f, 0x03} + }; + + +static u8 ZEBRA_AGC[] = { + 0, + 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, + 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, + 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, + 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, + 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, + 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24, + 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F + }; + +static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { + 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, + 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, + 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, + 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, + 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 }; -static u8 OFDM_CONFIG[] = { - /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ - /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ - /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ - - /* 0x00 */ - 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, - 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, - /* 0x10 */ - 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, - 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, - /* 0x20 */ - 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, - 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, - /* 0x30 */ - 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, - 0xD8, 0x3C, 0x7B, 0x10, 0x10 - }; - -/* --------------------------------------------------------------- - * Hardware IO - * the code is ported from Windows source code - ----------------------------------------------------------------*/ - -void -PlatformIOWrite1Byte( - struct net_device *dev, - u32 offset, - u8 data - ) +static u8 OFDM_CONFIG[] = { + /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ + /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ + /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ + /* 0x00 */ + 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, + 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, + /* 0x10 */ + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, + 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, + /* 0x20 */ + 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, + 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, + /* 0x30 */ + 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, + 0xD8, 0x3C, 0x7B, 0x10, 0x10 + }; + + /*--------------------------------------------------------------- + * Hardware IO + * the code is ported from Windows source code + *--------------------------------------------------------------- + */ + +void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data) { write_nic_byte(dev, offset, data); - read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ - + read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ } -void -PlatformIOWrite2Byte( - struct net_device *dev, - u32 offset, - u16 data - ) +void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data) { write_nic_word(dev, offset, data); read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ - - } + u8 PlatformIORead1Byte(struct net_device *dev, u32 offset); -void -PlatformIOWrite4Byte( - struct net_device *dev, - u32 offset, - u32 data - ) +void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) { -/* {by amy 080312 */ -if (offset == PhyAddr) { -/* For Base Band configuration. */ + if (offset == PhyAddr) { + /* For Base Band configuration. */ unsigned char cmdByte; unsigned long dataBytes; unsigned char idx; - u8 u1bTmp; + u8 u1bTmp; cmdByte = (u8)(data & 0x000000ff); dataBytes = data>>8; /* - 071010, rcnjko: - The critical section is only BB read/write race condition. - Assumption: - 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for - acquiring the spinlock in such context. - 2. PlatformIOWrite4Byte() MUST NOT be recursive. - */ -/* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ - - for (idx = 0; idx < 30; idx++) { - /* Make sure command bit is clear before access it. */ + * 071010, rcnjko: + * The critical section is only BB read/write race condition. + * Assumption: + * 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for + * acquiring the spinlock in such context. + * 2. PlatformIOWrite4Byte() MUST NOT be recursive. + */ + /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ + + for (idx = 0; idx < 30; idx++) { + /* Make sure command bit is clear before access it. */ u1bTmp = PlatformIORead1Byte(dev, PhyAddr); if ((u1bTmp & BIT7) == 0) break; @@ -186,20 +165,14 @@ if (offset == PhyAddr) { write_nic_byte(dev, offset, cmdByte); -/* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ - } -/* by amy 080312} */ - else { + /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ + } else { write_nic_dword(dev, offset, data); read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */ } } -u8 -PlatformIORead1Byte( - struct net_device *dev, - u32 offset - ) +u8 PlatformIORead1Byte(struct net_device *dev, u32 offset) { u8 data = 0; @@ -209,11 +182,7 @@ PlatformIORead1Byte( return data; } -u16 -PlatformIORead2Byte( - struct net_device *dev, - u32 offset - ) +u16 PlatformIORead2Byte(struct net_device *dev, u32 offset) { u16 data = 0; @@ -223,11 +192,7 @@ PlatformIORead2Byte( return data; } -u32 -PlatformIORead4Byte( - struct net_device *dev, - u32 offset - ) +u32 PlatformIORead4Byte(struct net_device *dev, u32 offset) { u32 data = 0; @@ -242,22 +207,19 @@ void SetOutputEnableOfRfPins(struct net_device *dev) write_nic_word(dev, RFPinsEnable, 0x1bff); } -static int -HwHSSIThreeWire( - struct net_device *dev, - u8 *pDataBuf, - u8 nDataBufBitCnt, - int bSI, - int bWrite - ) +static int HwHSSIThreeWire(struct net_device *dev, + u8 *pDataBuf, + u8 nDataBufBitCnt, + int bSI, + int bWrite) { int bResult = 1; u8 TryCnt; u8 u1bTmp; - do { + do { /* Check if WE and RE are cleared. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { u1bTmp = read_nic_byte(dev, SW_3W_CMD1); if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0) break; @@ -275,15 +237,15 @@ HwHSSIThreeWire( u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); if (bSI) - u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ + u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ else - u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ + u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - if (bSI) { + if (bSI) { /* jong: HW SI read must set reg84[3]=0. */ u1bTmp = read_nic_byte(dev, RFPinsSelect); u1bTmp &= ~BIT3; @@ -291,14 +253,14 @@ HwHSSIThreeWire( } /* Fill up data buffer for write operation. */ - if (bWrite) { - if (nDataBufBitCnt == 16) { + if (bWrite) { + if (nDataBufBitCnt == 16) { write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else if (nDataBufBitCnt == 64) { + } else if (nDataBufBitCnt == 64) { /* RTL8187S shouldn't enter this case */ write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); - } else { + } else { int idx; int ByteCnt = nDataBufBitCnt / 8; /* printk("%d\n",nDataBufBitCnt); */ @@ -324,11 +286,11 @@ HwHSSIThreeWire( write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); } - } else { /* read */ - if (bSI) { - /* SI - reg274[3:0] : RF register's Address */ + } else { /* read */ + if (bSI) { + /* SI - reg274[3:0] : RF register's Address */ write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else { + } else { /* PI - reg274[15:12] : RF register's Address */ write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12); } @@ -343,7 +305,7 @@ HwHSSIThreeWire( /* Check if DONE is set. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { u1bTmp = read_nic_byte(dev, SW_3W_CMD1); if ((u1bTmp & SW_3W_CMD1_DONE) != 0) break; @@ -353,12 +315,12 @@ HwHSSIThreeWire( write_nic_byte(dev, SW_3W_CMD1, 0); - /* Read back data for read operation. */ - if (bWrite == 0) { - if (bSI) { + /* Read back data for read operation. */ + if (bWrite == 0) { + if (bSI) { /* Serial Interface : reg363_362[11:0] */ *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ; - } else { + } else { /* Parallel Interface : reg361_360[11:0] */ *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ); } @@ -366,13 +328,12 @@ HwHSSIThreeWire( *((u16 *)pDataBuf) &= 0x0FFF; } - } while (0); + } while (0); return bResult; } -void -RF_WriteReg(struct net_device *dev, u8 offset, u32 data) +void RF_WriteReg(struct net_device *dev, u8 offset, u32 data) { u32 data2Write; u8 len; @@ -400,11 +361,7 @@ u32 RF_ReadReg(struct net_device *dev, u8 offset) /* by Owen on 04/07/14 for writing BB register successfully */ -void -WriteBBPortUchar( - struct net_device *dev, - u32 Data - ) +void WriteBBPortUchar(struct net_device *dev, u32 Data) { /* u8 TimeoutCounter; */ u8 RegisterContent; @@ -421,11 +378,7 @@ WriteBBPortUchar( } } -u8 -ReadBBPortUchar( - struct net_device *dev, - u32 addr - ) +u8 ReadBBPortUchar(struct net_device *dev, u32 addr) { /*u8 TimeoutCounter; */ u8 RegisterContent; @@ -435,66 +388,62 @@ ReadBBPortUchar( return RegisterContent; } -/* {by amy 080312 */ /* - Description: - Perform Antenna settings with antenna diversity on 87SE. - Created by Roger, 2008.01.25. -*/ -bool -SetAntennaConfig87SE( - struct net_device *dev, - u8 DefaultAnt, /* 0: Main, 1: Aux. */ - bool bAntDiversity /* 1:Enable, 0: Disable. */ -) + * Description: + * Perform Antenna settings with antenna diversity on 87SE. + * Created by Roger, 2008.01.25. + */ +bool SetAntennaConfig87SE(struct net_device *dev, + u8 DefaultAnt, /* 0: Main, 1: Aux. */ + bool bAntDiversity) /* 1:Enable, 0: Disable. */ { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); bool bAntennaSwitched = true; /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */ - /* Threshold for antenna diversity. */ + /* Threshold for antenna diversity. */ write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */ - if (bAntDiversity) { /* Enable Antenna Diversity. */ - if (DefaultAnt == 1) { /* aux antenna */ + if (bAntDiversity) { /* Enable Antenna Diversity. */ + if (DefaultAnt == 1) { /* aux antenna */ - /* Mac register, aux antenna */ + /* Mac register, aux antenna */ write_nic_byte(dev, ANTSEL, 0x00); - /* Config CCK RX antenna. */ + /* Config CCK RX antenna. */ write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ - write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ - } else { /* use main antenna */ - /* Mac register, main antenna */ + /* Config OFDM RX antenna. */ + write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ + write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ + } else { /* use main antenna */ + /* Mac register, main antenna */ write_nic_byte(dev, ANTSEL, 0x03); - /* base band */ - /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ - write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ + /* base band */ + /* Config CCK RX antenna. */ + write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ + write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */ /* Config OFDM RX antenna. */ write_phy_ofdm(dev, 0x0d, 0x5c); /* Reg0d : 5c */ write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */ } - } else { + } else { /* Disable Antenna Diversity. */ - if (DefaultAnt == 1) { /* aux Antenna */ + if (DefaultAnt == 1) { /* aux Antenna */ /* Mac register, aux antenna */ write_nic_byte(dev, ANTSEL, 0x00); /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ - write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ + write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ + write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ - write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */ - } else { /* main Antenna */ + write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ + write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */ + } else { /* main Antenna */ /* Mac register, main antenna */ write_nic_byte(dev, ANTSEL, 0x03); @@ -502,25 +451,22 @@ SetAntennaConfig87SE( write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */ - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */ - write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */ + /* Config OFDM RX antenna. */ + write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */ + write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */ } } priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */ return bAntennaSwitched; } -/* by amy 080312 */ /* ---------------------------------------------------------------- - * Hardware Initialization. - * the code is ported from Windows source code -----------------------------------------------------------------*/ - -void -ZEBRA_Config_85BASIC_HardCode( - struct net_device *dev - ) + *-------------------------------------------------------------- + * Hardware Initialization. + * the code is ported from Windows source code + *-------------------------------------------------------------- + */ + +void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -532,163 +478,151 @@ ZEBRA_Config_85BASIC_HardCode( /* -============================================================================= - 87S_PCIE :: RADIOCFG.TXT -============================================================================= -*/ + *=========================================================================== + * 87S_PCIE :: RADIOCFG.TXT + *=========================================================================== + */ /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */ - u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1); - u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1); + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */ + u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1); + u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1); if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) { d_cut = 1; printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n"); } - /* Page0 : reg0-reg15 */ - - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */ - - RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); - - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */ - - RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */ - - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); - RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1); - RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1); - RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1); - RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1); - RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1); - RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1); - + /* Page0 : reg0-reg15 */ + + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */ + RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */ + RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */ + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); + RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1); + RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1); + RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1); + RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1); + RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1); + RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1); + RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1); + RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1); /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); - - RF_WriteReg(dev, 0x03, 0x0806); mdelay(1); - - RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1); - RF_WriteReg(dev, 0x05, 0x059b); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0081); mdelay(1); - - - RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); + RF_WriteReg(dev, 0x03, 0x0806); mdelay(1); + RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1); + RF_WriteReg(dev, 0x05, 0x059b); mdelay(1); + RF_WriteReg(dev, 0x06, 0x0081); mdelay(1); + RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); /* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */ - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); + RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); if (d_cut) { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */ - } else { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */ + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */ + } else { + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); + RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */ } - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); - - RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */ + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); + RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */ + RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); + RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1); - RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); - RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1); - for (i = 0; i <= 36; i++) { - RF_WriteReg(dev, 0x01, i); mdelay(1); + for (i = 0; i <= 36; i++) { + RF_WriteReg(dev, 0x01, i); mdelay(1); RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); } - RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */ - RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */ + RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */ + RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */ + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */ + mdelay(200); /* Deay 200 ms. */ /* 0xfd */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */ - mdelay(200); /* Deay 200 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */ + mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - RF_WriteReg(dev, 0x07, 0x0000); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0180); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0220); mdelay(1); - RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0000); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0180); mdelay(1); + RF_WriteReg(dev, 0x07, 0x0220); mdelay(1); + RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1); /* DAC calibration off 20070702 */ - RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); -/* {by amy 080312 */ + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); /* For crystal calibration, added by Roger, 2007.12.11. */ - if (priv->bXtalCalibration) { /* reg 30. */ - /* enable crystal calibration. - RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. - (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0 - (3)RF signal on/off when calibration[13], default: on, set BIT13=0. - So we should minus 4 BITs offset. */ - RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); + if (priv->bXtalCalibration) { /* reg 30. */ + /* + * enable crystal calibration. + * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. + * (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0 + * (3)RF signal on/off when calibration[13], default: on, set BIT13=0. + * So we should minus 4 BITs offset. + */ + RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", - (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); - } else { + (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); + } else { /* using default value. Xin=6, Xout=6. */ - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); } -/* by amy 080312 */ - RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */ - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */ - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */ - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */ + RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */ + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */ + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */ + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ - RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */ - - RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ - /* power save parameters. */ + RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ + RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */ + /* power save parameters. */ u1b24E = read_nic_byte(dev, 0x24E); write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6)))); /*============================================================================= - - ============================================================================= - CCKCONF.TXT - ============================================================================= - */ - /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27 - CCK reg0x00[7]=1'b1 :power saving for TX (default) - CCK reg0x00[6]=1'b1: power saving for RX (default) - CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation. - CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1 - CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0 - */ + * + *=========================================================================== + * CCKCONF.TXT + *=========================================================================== + * + * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27 + * CCK reg0x00[7]=1'b1 :power saving for TX (default) + * CCK reg0x00[6]=1'b1: power saving for RX (default) + * CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation. + * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1 + * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0 + */ write_phy_cck(dev, 0x00, 0xc8); write_phy_cck(dev, 0x06, 0x1c); @@ -697,7 +631,7 @@ ZEBRA_Config_85BASIC_HardCode( write_phy_cck(dev, 0x2f, 0x06); write_phy_cck(dev, 0x01, 0x46); - /* power control */ + /* power control */ write_nic_byte(dev, CCK_TXAGC, 0x10); write_nic_byte(dev, OFDM_TXAGC, 0x1B); write_nic_byte(dev, ANTSEL, 0x03); @@ -705,14 +639,14 @@ ZEBRA_Config_85BASIC_HardCode( /* - ============================================================================= - AGC.txt - ============================================================================= - */ + *=========================================================================== + * AGC.txt + *=========================================================================== + */ write_phy_ofdm(dev, 0x00, 0x12); - for (i = 0; i < 128; i++) { + for (i = 0; i < 128; i++) { data = ZEBRA_AGC[i+1]; data = data << 8; @@ -730,49 +664,43 @@ ZEBRA_Config_85BASIC_HardCode( PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */ /* - ============================================================================= - - ============================================================================= - OFDMCONF.TXT - ============================================================================= - */ - - for (i = 0; i < 60; i++) { + *=========================================================================== + * + *=========================================================================== + * OFDMCONF.TXT + *=========================================================================== + */ + + for (i = 0; i < 60; i++) { u4bRegOffset = i; u4bRegValue = OFDM_CONFIG[i]; WriteBBPortUchar(dev, - (0x00000080 | - (u4bRegOffset & 0x7f) | - ((u4bRegValue & 0xff) << 8))); + (0x00000080 | + (u4bRegOffset & 0x7f) | + ((u4bRegValue & 0xff) << 8))); } /* - ============================================================================= - by amy for antenna - ============================================================================= - */ -/* {by amy 080312 */ + *=========================================================================== + * by amy for antenna + *=========================================================================== + */ /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */ SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity); -/* by amy 080312} */ -/* by amy for antenna */ } -void -UpdateInitialGain( - struct net_device *dev - ) +void UpdateInitialGain(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* lzm add 080826 */ - if (priv->eRFPowerState != eRfOn) { + if (priv->eRFPowerState != eRfOn) { /* Don't access BB/RF under disable PLL situation. - RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n")); - Back to the original state - */ + * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n")); + * Back to the original state + */ priv->InitialGain = priv->InitialGainBackUp; return; } @@ -826,7 +754,7 @@ UpdateInitialGain( write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); break; - default: /* MP */ + default: /* MP */ write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); @@ -834,14 +762,11 @@ UpdateInitialGain( } } /* - Description: - Tx Power tracking mechanism routine on 87SE. - Created by Roger, 2007.12.11. -*/ -void -InitTxPwrTracking87SE( - struct net_device *dev -) + * Description: + * Tx Power tracking mechanism routine on 87SE. + * Created by Roger, 2007.12.11. + */ +void InitTxPwrTracking87SE(struct net_device *dev) { u32 u4bRfReg; @@ -851,49 +776,41 @@ InitTxPwrTracking87SE( RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1); } -void -PhyConfig8185( - struct net_device *dev - ) +void PhyConfig8185(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); write_nic_dword(dev, RCR, priv->ReceiveConfig); priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03; /* RF config */ ZEBRA_Config_85BASIC_HardCode(dev); -/* {by amy 080312 */ /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */ - if (priv->bDigMechanism) { + if (priv->bDigMechanism) { if (priv->InitialGain == 0) priv->InitialGain = 4; } /* - Enable thermal meter indication to implement TxPower tracking on 87SE. - We initialize thermal meter here to avoid unsuccessful configuration. - Added by Roger, 2007.12.11. - */ + * Enable thermal meter indication to implement TxPower tracking on 87SE. + * We initialize thermal meter here to avoid unsuccessful configuration. + * Added by Roger, 2007.12.11. + */ if (priv->bTxPowerTrack) InitTxPwrTracking87SE(dev); -/* by amy 080312} */ priv->InitialGainBackUp = priv->InitialGain; UpdateInitialGain(dev); return; } -void -HwConfigureRTL8185( - struct net_device *dev - ) +void HwConfigureRTL8185(struct net_device *dev) { /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */ - u8 bUNIVERSAL_CONTROL_RL = 0; - u8 bUNIVERSAL_CONTROL_AGC = 1; - u8 bUNIVERSAL_CONTROL_ANT = 1; - u8 bAUTO_RATE_FALLBACK_CTL = 1; - u8 val8; + u8 bUNIVERSAL_CONTROL_RL = 0; + u8 bUNIVERSAL_CONTROL_AGC = 1; + u8 bUNIVERSAL_CONTROL_ANT = 1; + u8 bAUTO_RATE_FALLBACK_CTL = 1; + u8 val8; write_nic_word(dev, BRSR, 0x0fff); /* Retry limit */ val8 = read_nic_byte(dev, CW_CONF); @@ -907,24 +824,24 @@ HwConfigureRTL8185( /* Tx AGC */ val8 = read_nic_byte(dev, TXAGC_CTL); - if (bUNIVERSAL_CONTROL_AGC) { + if (bUNIVERSAL_CONTROL_AGC) { write_nic_byte(dev, CCK_TXAGC, 128); write_nic_byte(dev, OFDM_TXAGC, 128); val8 = val8 & 0xfe; - } else { + } else { val8 = val8 | 0x01 ; } write_nic_byte(dev, TXAGC_CTL, val8); - /* Tx Antenna including Feedback control */ + /* Tx Antenna including Feedback control */ val8 = read_nic_byte(dev, TXAGC_CTL); - if (bUNIVERSAL_CONTROL_ANT) { + if (bUNIVERSAL_CONTROL_ANT) { write_nic_byte(dev, ANTSEL, 0x00); val8 = val8 & 0xfd; - } else { + } else { val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */ } @@ -933,7 +850,7 @@ HwConfigureRTL8185( /* Auto Rate fallback control */ val8 = read_nic_byte(dev, RATE_FALLBACK); val8 &= 0x7c; - if (bAUTO_RATE_FALLBACK_CTL) { + if (bAUTO_RATE_FALLBACK_CTL) { val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1; /* <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. */ @@ -942,40 +859,34 @@ HwConfigureRTL8185( write_nic_byte(dev, RATE_FALLBACK, val8); } -static void -MacConfig_85BASIC_HardCode( - struct net_device *dev) +static void MacConfig_85BASIC_HardCode(struct net_device *dev) { /* - ============================================================================ - MACREG.TXT - ============================================================================ - */ - int nLinesRead = 0; - - u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; - int i; + *========================================================================== + * MACREG.TXT + *========================================================================== + */ + int nLinesRead = 0; + u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; + int i; nLinesRead = sizeof(MAC_REG_TABLE)/2; - for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */ + for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */ u4bRegOffset = MAC_REG_TABLE[i][0]; u4bRegValue = MAC_REG_TABLE[i][1]; if (u4bRegOffset == 0x5e) u4bPageIndex = u4bRegValue; - else - u4bRegOffset |= (u4bPageIndex << 8); + u4bRegOffset |= (u4bPageIndex << 8); write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); } /* ============================================================================ */ } -static void -MacConfig_85BASIC( - struct net_device *dev) +static void MacConfig_85BASIC(struct net_device *dev) { u8 u1DA; @@ -994,18 +905,18 @@ MacConfig_85BASIC( PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000); PlatformIOWrite1Byte(dev, 0x1F8, 0x00); - /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */ - /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */ + /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */ + /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */ /* Enable DA10 TX power saving */ u1DA = read_nic_byte(dev, PHYPR); write_nic_byte(dev, PHYPR, (u1DA | BIT2)); - /* POWER: */ + /* POWER: */ write_nic_word(dev, 0x360, 0x1000); write_nic_word(dev, 0x362, 0x1000); - /* AFE. */ + /* AFE. */ write_nic_word(dev, 0x370, 0x0560); write_nic_word(dev, 0x372, 0x0560); write_nic_word(dev, 0x374, 0x0DA4); @@ -1013,54 +924,48 @@ MacConfig_85BASIC( write_nic_word(dev, 0x378, 0x0560); write_nic_word(dev, 0x37A, 0x0560); write_nic_word(dev, 0x37C, 0x00EC); - write_nic_word(dev, 0x37E, 0x00EC); /*+edward */ + write_nic_word(dev, 0x37E, 0x00EC); /* +edward */ write_nic_byte(dev, 0x24E, 0x01); } -u8 -GetSupportedWirelessMode8185( - struct net_device *dev -) +u8 GetSupportedWirelessMode8185(struct net_device *dev) { - u8 btSupportedWirelessMode = 0; + u8 btSupportedWirelessMode = 0; btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); return btSupportedWirelessMode; } -void -ActUpdateChannelAccessSetting( - struct net_device *dev, - WIRELESS_MODE WirelessMode, - PCHANNEL_ACCESS_SETTING ChnlAccessSetting - ) +void ActUpdateChannelAccessSetting(struct net_device *dev, + WIRELESS_MODE WirelessMode, + PCHANNEL_ACCESS_SETTING ChnlAccessSetting) { - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; + struct r8180_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; AC_CODING eACI; AC_PARAM AcParam; - u8 bFollowLegacySetting = 0; - u8 u1bAIFS; + u8 bFollowLegacySetting = 0; + u8 u1bAIFS; /* - <RJ_TODO_8185B> - TODO: We still don't know how to set up these registers, just follow WMAC to - verify 8185B FPAG. - - <RJ_TODO_8185B> - Jong said CWmin/CWmax register are not functional in 8185B, - so we shall fill channel access realted register into AC parameter registers, - even in nQBss. - */ + * <RJ_TODO_8185B> + * TODO: We still don't know how to set up these registers, just follow WMAC to + * verify 8185B FPAG. + * + * <RJ_TODO_8185B> + * Jong said CWmin/CWmax register are not functional in 8185B, + * so we shall fill channel access realted register into AC parameter registers, + * even in nQBss. + */ ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */ - ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */ - ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */ - ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */ + ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */ + ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */ write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer); - write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */ + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */ u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer); @@ -1074,17 +979,17 @@ ActUpdateChannelAccessSetting( } /* this setting is copied from rtl8187B. xiong-2006-11-13 */ - if (bFollowLegacySetting) { + if (bFollowLegacySetting) { /* - Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. - 2005.12.01, by rcnjko. - */ + * Follow 802.11 seeting to AC parameter, all AC shall use the same parameter. + * 2005.12.01, by rcnjko. + */ AcParam.longData = 0; AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */ AcParam.f.AciAifsn.f.ACM = 0; - AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */ - AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */ + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */ + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */ AcParam.f.TXOPLimit = 0; /* lzm reserved 080826 */ @@ -1095,7 +1000,7 @@ ActUpdateChannelAccessSetting( if (ieee->iw_mode == IW_MODE_ADHOC) AcParam.f.TXOPLimit = 0x0020; - for (eACI = 0; eACI < AC_MAX; eACI++) { + for (eACI = 0; eACI < AC_MAX; eACI++) { AcParam.f.AciAifsn.f.ACI = (u8)eACI; { PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam); @@ -1103,7 +1008,7 @@ ActUpdateChannelAccessSetting( u8 u1bAIFS; u32 u4bAcParam; - /* Retrive paramters to udpate. */ + /* Retrieve paramters to update. */ eACI = pAcParam->f.AciAifsn.f.ACI; u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime; u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) | @@ -1111,7 +1016,7 @@ ActUpdateChannelAccessSetting( (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) | (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); - switch (eACI) { + switch (eACI) { case AC1_BK: /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */ break; @@ -1133,47 +1038,46 @@ ActUpdateChannelAccessSetting( break; } - /* Cehck ACM bit. */ + /* Cehck ACM bit. */ /* If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. */ { PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn); AC_CODING eACI = pAciAifsn->f.ACI; - /*modified Joseph */ - /*for 8187B AsynIORead issue */ + /*for 8187B AsynIORead issue */ u8 AcmCtrl = 0; - if (pAciAifsn->f.ACM) { + if (pAciAifsn->f.ACM) { /* ACM bit is 1. */ - switch (eACI) { + switch (eACI) { case AC0_BE: - AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */ + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */ break; case AC2_VI: - AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */ + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */ break; case AC3_VO: - AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */ + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */ break; default: DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI); break; } - } else { + } else { /* ACM bit is 0. */ - switch (eACI) { + switch (eACI) { case AC0_BE: - AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */ + AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */ break; case AC2_VI: - AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */ + AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */ break; case AC3_VO: - AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */ + AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */ break; default: @@ -1187,53 +1091,51 @@ ActUpdateChannelAccessSetting( } } -void -ActSetWirelessMode8185( - struct net_device *dev, - u8 btWirelessMode - ) +void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee80211; u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev); if ((btWirelessMode & btSupportedWirelessMode) == 0) { - /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */ + /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */ DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n", btWirelessMode, btSupportedWirelessMode); return; } - /* 1. Assign wireless mode to swtich if necessary. */ - if (btWirelessMode == WIRELESS_MODE_AUTO) { - if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { + /* 1. Assign wireless mode to switch if necessary. */ + if (btWirelessMode == WIRELESS_MODE_AUTO) { + if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { btWirelessMode = WIRELESS_MODE_A; - } else if (btSupportedWirelessMode & WIRELESS_MODE_G) { + } else if (btSupportedWirelessMode & WIRELESS_MODE_G) { btWirelessMode = WIRELESS_MODE_G; - } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) { - btWirelessMode = WIRELESS_MODE_B; - } else { - DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n", - btSupportedWirelessMode); + } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) { btWirelessMode = WIRELESS_MODE_B; + } else { + DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n", + btSupportedWirelessMode); + btWirelessMode = WIRELESS_MODE_B; } } - /* 2. Swtich band: RF or BB specific actions, + /* + * 2. Swtich band: RF or BB specific actions, * for example, refresh tables in omc8255, or change initial gain if necessary. * Nothing to do for Zebra to switch band. - * Update current wireless mode if we swtich to specified band successfully. */ + * Update current wireless mode if we switch to specified band successfully. + */ ieee->mode = (WIRELESS_MODE)btWirelessMode; - /* 3. Change related setting. */ - if( ieee->mode == WIRELESS_MODE_A ) { + /* 3. Change related setting. */ + if( ieee->mode == WIRELESS_MODE_A ) { DMESG("WIRELESS_MODE_A\n"); - } else if( ieee->mode == WIRELESS_MODE_B ) { - DMESG("WIRELESS_MODE_B\n"); - } else if( ieee->mode == WIRELESS_MODE_G ) { - DMESG("WIRELESS_MODE_G\n"); + } else if( ieee->mode == WIRELESS_MODE_B ) { + DMESG("WIRELESS_MODE_B\n"); + } else if( ieee->mode == WIRELESS_MODE_G ) { + DMESG("WIRELESS_MODE_G\n"); } ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting); } @@ -1245,22 +1147,16 @@ void rtl8185b_irq_enable(struct net_device *dev) priv->irq_enabled = 1; write_nic_dword(dev, IMR, priv->IntrMask); } -/* by amy for power save */ -void -DrvIFIndicateDisassociation( - struct net_device *dev, - u16 reason - ) + +void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason) { /* nothing is needed after disassociation request. */ - } -void -MgntDisconnectIBSS( - struct net_device *dev -) +} + +void MgntDisconnectIBSS(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u8 i; + u8 i; DrvIFIndicateDisassociation(dev, unspec_reason); @@ -1271,166 +1167,143 @@ MgntDisconnectIBSS( priv->ieee80211->state = IEEE80211_NOLINK; /* - Stop Beacon. - - Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST - Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck. - Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. - - Disable Beacon Queue Own bit, suggested by jong */ + * Stop Beacon. + * + * Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST + * Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck. + * Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send. + * + * Disable Beacon Queue Own bit, suggested by jong + */ ieee80211_stop_send_beacons(priv->ieee80211); priv->ieee80211->link_change(dev); notify_wx_assoc_event(priv->ieee80211); } -void -MlmeDisassociateRequest( - struct net_device *dev, - u8 *asSta, - u8 asRsn - ) + +void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u8 i; SendDisassociation(priv->ieee80211, asSta, asRsn); - if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { - /*ShuChen TODO: change media status. */ - /*ShuChen TODO: What to do when disassociate. */ + if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { + /* ShuChen TODO: change media status. */ + /* ShuChen TODO: What to do when disassociate. */ DrvIFIndicateDisassociation(dev, unspec_reason); - - for (i = 0; i < 6; i++) priv->ieee80211->current_network.bssid[i] = 0x22; ieee80211_disassociate(priv->ieee80211); } - } -void -MgntDisconnectAP( - struct net_device *dev, - u8 asRsn -) +void MgntDisconnectAP(struct net_device *dev, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - Commented out by rcnjko, 2005.01.27: - I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). - - 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success - - In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. - 2004.10.11, by rcnjko. */ + * Commented out by rcnjko, 2005.01.27: + * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). + * + * 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success + * + * In WPA WPA2 need to Clear all key ... because new key will set after new handshaking. + * 2004.10.11, by rcnjko. + */ MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn); priv->ieee80211->state = IEEE80211_NOLINK; } -bool -MgntDisconnect( - struct net_device *dev, - u8 asRsn -) + +bool MgntDisconnect(struct net_device *dev, u8 asRsn) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - Schedule an workitem to wake up for ps mode, 070109, by rcnjko. - */ + * Schedule an workitem to wake up for ps mode, 070109, by rcnjko. + */ if (IS_DOT11D_ENABLE(priv->ieee80211)) Dot11d_Reset(priv->ieee80211); - /* In adhoc mode, update beacon frame. */ + /* In adhoc mode, update beacon frame. */ if (priv->ieee80211->state == IEEE80211_LINKED) { if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) MgntDisconnectIBSS(dev); - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { - /* We clear key here instead of MgntDisconnectAP() because that - MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, - e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is - used to handle disassociation related things to AP, e.g. send Disassoc - frame to AP. 2005.01.27, by rcnjko. */ + if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { + /* + * We clear key here instead of MgntDisconnectAP() because that + * MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, + * e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is + * used to handle disassociation related things to AP, e.g. send Disassoc + * frame to AP. 2005.01.27, by rcnjko. + */ MgntDisconnectAP(dev, asRsn); } - /* Inidicate Disconnect, 2005.02.23, by rcnjko. */ + /* Indicate Disconnect, 2005.02.23, by rcnjko. */ } return true; } /* - Description: - Chang RF Power State. - Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. - - Assumption: - PASSIVE LEVEL. -*/ -bool -SetRFPowerState( - struct net_device *dev, - RT_RF_POWER_STATE eRFPowerState - ) + * Description: + * Chang RF Power State. + * Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. + * + * Assumption: + * PASSIVE LEVEL. + */ +bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bResult = false; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bResult = false; if (eRFPowerState == priv->eRFPowerState) return bResult; - bResult = SetZebraRFPowerState8185(dev, eRFPowerState); + bResult = SetZebraRFPowerState8185(dev, eRFPowerState); return bResult; } -void -HalEnableRx8185Dummy( - struct net_device *dev - ) + +void HalEnableRx8185Dummy(struct net_device *dev) { } -void -HalDisableRx8185Dummy( - struct net_device *dev - ) + +void HalDisableRx8185Dummy(struct net_device *dev) { } -bool -MgntActSet_RF_State( - struct net_device *dev, - RT_RF_POWER_STATE StateToSet, - u32 ChangeSource - ) +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource) { - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bActionAllowed = false; - bool bConnectBySSID = false; - RT_RF_POWER_STATE rtState; - u16 RFWaitCounter = 0; + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); + bool bActionAllowed = false; + bool bConnectBySSID = false; + RT_RF_POWER_STATE rtState; + u16 RFWaitCounter = 0; unsigned long flag; /* - Prevent the race condition of RF state change. By Bruce, 2007-11-28. - Only one thread can change the RF state at one time, and others should wait to be executed. - */ - while (true) { + * Prevent the race condition of RF state change. By Bruce, 2007-11-28. + * Only one thread can change the RF state at one time, and others should wait to be executed. + */ + while (true) { spin_lock_irqsave(&priv->rf_ps_lock, flag); - if (priv->RFChangeInProgress) { + if (priv->RFChangeInProgress) { spin_unlock_irqrestore(&priv->rf_ps_lock, flag); /* Set RF after the previous action is done. */ - while (priv->RFChangeInProgress) { + while (priv->RFChangeInProgress) { RFWaitCounter++; udelay(1000); /* 1 ms */ - /* Wait too long, return FALSE to avoid to be stuck here. */ - if (RFWaitCounter > 1000) { /* 1sec */ + /* Wait too long, return FALSE to avoid to be stuck here. */ + if (RFWaitCounter > 1000) { /* 1sec */ printk("MgntActSet_RF_State(): Wait too long to set RF\n"); - /* TODO: Reset RF state? */ + /* TODO: Reset RF state? */ return false; } } - } else { + } else { priv->RFChangeInProgress = true; spin_unlock_irqrestore(&priv->rf_ps_lock, flag); break; @@ -1438,12 +1311,12 @@ MgntActSet_RF_State( } rtState = priv->eRFPowerState; - switch (StateToSet) { + switch (StateToSet) { case eRfOn: /* - Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or - the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. - */ + * Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or + * the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02. + */ priv->RfOffReason &= (~ChangeSource); if (!priv->RfOffReason) { @@ -1453,25 +1326,24 @@ MgntActSet_RF_State( if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest) bConnectBySSID = true; - } else - ; + } else + ; break; case eRfOff: - /* 070125, rcnjko: we always keep connected in AP mode. */ - - if (priv->RfOffReason > RF_CHANGE_BY_IPS) { - /* - 060808, Annie: - Disconnect to current BSS when radio off. Asked by QuanTa. - - Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), - because we do NOT need to set ssid to dummy ones. - */ - MgntDisconnect(dev, disas_lv_ss); - - /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */ - } + /* 070125, rcnjko: we always keep connected in AP mode. */ + + if (priv->RfOffReason > RF_CHANGE_BY_IPS) { + /* + * 060808, Annie: + * Disconnect to current BSS when radio off. Asked by QuanTa. + * + * Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(), + * because we do NOT need to set ssid to dummy ones. + */ + MgntDisconnect(dev, disas_lv_ss); + /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */ + } priv->RfOffReason |= ChangeSource; bActionAllowed = true; @@ -1484,14 +1356,14 @@ MgntActSet_RF_State( break; } - if (bActionAllowed) { - /* Config HW to the specified mode. */ + if (bActionAllowed) { + /* Config HW to the specified mode. */ SetRFPowerState(dev, StateToSet); /* Turn on RF. */ - if (StateToSet == eRfOn) { + if (StateToSet == eRfOn) { HalEnableRx8185Dummy(dev); - if (bConnectBySSID) { + if (bConnectBySSID) { /* by amy not supported */ } } @@ -1507,69 +1379,61 @@ MgntActSet_RF_State( spin_unlock_irqrestore(&priv->rf_ps_lock, flag); return bActionAllowed; } -void -InactivePowerSave( - struct net_device *dev - ) + +void InactivePowerSave(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); /* - This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem - is really scheduled. - The old code, sets this flag before scheduling the IPS workitem and however, at the same time the - previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing - blocks the IPS procedure of switching RF. - */ + * This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem + * is really scheduled. + * The old code, sets this flag before scheduling the IPS workitem and however, at the same time the + * previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing + * blocks the IPS procedure of switching RF. + */ priv->bSwRfProcessing = true; MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS); /* - To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. - */ + * To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. + */ priv->bSwRfProcessing = false; } /* - Description: - Enter the inactive power save mode. RF will be off -*/ -void -IPSEnter( - struct net_device *dev - ) + * Description: + * Enter the inactive power save mode. RF will be off + */ +void IPSEnter(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - if (priv->bInactivePs) { + if (priv->bInactivePs) { rtState = priv->eRFPowerState; /* - Do not enter IPS in the following conditions: - (1) RF is already OFF or Sleep - (2) bSwRfProcessing (indicates the IPS is still under going) - (3) Connectted (only disconnected can trigger IPS) - (4) IBSS (send Beacon) - (5) AP mode (send Beacon) - */ + * Do not enter IPS in the following conditions: + * (1) RF is already OFF or Sleep + * (2) bSwRfProcessing (indicates the IPS is still under going) + * (3) Connected (only disconnected can trigger IPS) + * (4) IBSS (send Beacon) + * (5) AP mode (send Beacon) + */ if (rtState == eRfOn && !priv->bSwRfProcessing - && (priv->ieee80211->state != IEEE80211_LINKED)) { + && (priv->ieee80211->state != IEEE80211_LINKED)) { priv->eInactivePowerState = eRfOff; InactivePowerSave(dev); } } } -void -IPSLeave( - struct net_device *dev - ) +void IPSLeave(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); RT_RF_POWER_STATE rtState; - if (priv->bInactivePs) { + if (priv->bInactivePs) { rtState = priv->eRFPowerState; - if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) { + if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) { priv->eInactivePowerState = eRfOn; InactivePowerSave(dev); } @@ -1582,8 +1446,8 @@ void rtl8185b_adapter_start(struct net_device *dev) struct ieee80211_device *ieee = priv->ieee80211; u8 SupportedWirelessMode; - u8 InitWirelessMode; - u8 bInvalidWirelessMode = 0; + u8 InitWirelessMode; + u8 bInvalidWirelessMode = 0; u8 tmpu8; u8 btCR9346; u8 TmpU1b; @@ -1598,89 +1462,89 @@ void rtl8185b_adapter_start(struct net_device *dev) HwConfigureRTL8185(dev); write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff); - write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */ + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */ write_nic_word(dev, BcnItv, 100); write_nic_word(dev, AtimWnd, 2); PlatformIOWrite2Byte(dev, FEMR, 0xFFFF); write_nic_byte(dev, WPA_CONFIG, 0); MacConfig_85BASIC(dev); - /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */ - /* BT_DEMO_BOARD type */ + /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */ + /* BT_DEMO_BOARD type */ PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); /* - ----------------------------------------------------------------------------- - Set up PHY related. - ----------------------------------------------------------------------------- - */ - /* Enable Config3.PARAM_En to revise AnaaParm. */ - write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ + *--------------------------------------------------------------------------- + * Set up PHY related. + *--------------------------------------------------------------------------- + */ + /* Enable Config3.PARAM_En to revise AnaaParm. */ + write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ tmpu8 = read_nic_byte(dev, CONFIG3); write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En)); - /* Turn on Analog power. */ - /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */ + /* Turn on Analog power. */ + /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */ write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); write_nic_word(dev, ANAPARAM3, 0x0010); write_nic_byte(dev, CONFIG3, tmpu8); write_nic_byte(dev, CR9346, 0x00); - /* enable EEM0 and EEM1 in 9346CR */ + /* enable EEM0 and EEM1 in 9346CR */ btCR9346 = read_nic_byte(dev, CR9346); write_nic_byte(dev, CR9346, (btCR9346 | 0xC0)); - /* B cut use LED1 to control HW RF on/off */ + /* B cut use LED1 to control HW RF on/off */ TmpU1b = read_nic_byte(dev, CONFIG5); TmpU1b = TmpU1b & ~BIT3; write_nic_byte(dev, CONFIG5, TmpU1b); - /* disable EEM0 and EEM1 in 9346CR */ + /* disable EEM0 and EEM1 in 9346CR */ btCR9346 &= ~(0xC0); write_nic_byte(dev, CR9346, btCR9346); - /* Enable Led (suggested by Jong) */ - /* B-cut RF Radio on/off 5e[3]=0 */ + /* Enable Led (suggested by Jong) */ + /* B-cut RF Radio on/off 5e[3]=0 */ btPSR = read_nic_byte(dev, PSR); write_nic_byte(dev, PSR, (btPSR | BIT3)); - /* setup initial timing for RFE. */ + /* setup initial timing for RFE. */ write_nic_word(dev, RFPinsOutput, 0x0480); SetOutputEnableOfRfPins(dev); write_nic_word(dev, RFPinsSelect, 0x2488); - /* PHY config. */ + /* PHY config. */ PhyConfig8185(dev); /* - We assume RegWirelessMode has already been initialized before, - however, we has to validate the wireless mode here and provide a - reasonable initialized value if necessary. 2005.01.13, by rcnjko. - */ + * We assume RegWirelessMode has already been initialized before, + * however, we has to validate the wireless mode here and provide a + * reasonable initialized value if necessary. 2005.01.13, by rcnjko. + */ SupportedWirelessMode = GetSupportedWirelessMode8185(dev); if ((ieee->mode != WIRELESS_MODE_B) && (ieee->mode != WIRELESS_MODE_G) && (ieee->mode != WIRELESS_MODE_A) && - (ieee->mode != WIRELESS_MODE_AUTO)) { - /* It should be one of B, G, A, or AUTO. */ + (ieee->mode != WIRELESS_MODE_AUTO)) { + /* It should be one of B, G, A, or AUTO. */ bInvalidWirelessMode = 1; - } else { - /* One of B, G, A, or AUTO. */ - /* Check if the wireless mode is supported by RF. */ + } else { + /* One of B, G, A, or AUTO. */ + /* Check if the wireless mode is supported by RF. */ if ((ieee->mode != WIRELESS_MODE_AUTO) && - (ieee->mode & SupportedWirelessMode) == 0) { + (ieee->mode & SupportedWirelessMode) == 0) { bInvalidWirelessMode = 1; } } - if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) { - /* Auto or other invalid value. */ - /* Assigne a wireless mode to initialize. */ - if ((SupportedWirelessMode & WIRELESS_MODE_A)) { + if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) { + /* Auto or other invalid value. */ + /* Assigne a wireless mode to initialize. */ + if ((SupportedWirelessMode & WIRELESS_MODE_A)) { InitWirelessMode = WIRELESS_MODE_A; - } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) { + } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) { InitWirelessMode = WIRELESS_MODE_G; - } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) { + } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) { InitWirelessMode = WIRELESS_MODE_B; - } else { + } else { DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", SupportedWirelessMode); InitWirelessMode = WIRELESS_MODE_B; @@ -1690,24 +1554,21 @@ void rtl8185b_adapter_start(struct net_device *dev) if (bInvalidWirelessMode) ieee->mode = (WIRELESS_MODE)InitWirelessMode; - } else { - /* One of B, G, A. */ + } else { + /* One of B, G, A. */ InitWirelessMode = ieee->mode; } -/* by amy for power save */ priv->eRFPowerState = eRfOff; priv->RfOffReason = 0; { MgntActSet_RF_State(dev, eRfOn, 0); } /* - If inactive power mode is enabled, disable rf while in disconnected state. - */ + * If inactive power mode is enabled, disable rf while in disconnected state. + */ if (priv->bInactivePs) MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS); -/* by amy for power save */ - ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); /* ----------------------------------------------------------------------------- */ @@ -1715,7 +1576,7 @@ void rtl8185b_adapter_start(struct net_device *dev) rtl8185b_irq_enable(dev); netif_start_queue(dev); - } +} void rtl8185b_rx_enable(struct net_device *dev) { @@ -1728,7 +1589,7 @@ void rtl8185b_rx_enable(struct net_device *dev) DMESG("NIC in promisc mode"); if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ - dev->flags & IFF_PROMISC) { + dev->flags & IFF_PROMISC) { priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM); priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP; } diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig index f87e211..4602a47 100644 --- a/drivers/staging/rtl8192e/Kconfig +++ b/drivers/staging/rtl8192e/Kconfig @@ -14,6 +14,7 @@ if RTLLIB config RTLLIB_CRYPTO_CCMP tristate "Support for rtllib CCMP crypto" depends on RTLLIB + select CRYPTO_AES default y ---help--- CCMP crypto driver for rtllib. @@ -23,6 +24,8 @@ config RTLLIB_CRYPTO_CCMP config RTLLIB_CRYPTO_TKIP tristate "Support for rtllib TKIP crypto" depends on RTLLIB + select CRYPTO_ARC4 + select CRYPTO_MICHAEL_MIC default y ---help--- TKIP crypto driver for rtllib. @@ -31,6 +34,7 @@ config RTLLIB_CRYPTO_TKIP config RTLLIB_CRYPTO_WEP tristate "Support for rtllib WEP crypto" + select CRYPTO_ARC4 depends on RTLLIB default y ---help--- diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c index 58d044e..ea91744 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c @@ -342,7 +342,6 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) u32 cmpk_message_handle_rx(struct net_device *dev, struct rtllib_rx_stats *pstats) { - struct r8192_priv *priv = rtllib_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; @@ -409,8 +408,6 @@ u32 cmpk_message_handle_rx(struct net_device *dev, return 1; } - priv->stats.rxcmdpkt[element_id]++; - total_length -= cmd_length; pcmd_buff += cmd_length; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c index 3771985..b526fa4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c @@ -216,7 +216,7 @@ static bool firmware_check_ready(struct net_device *dev, break; default: rt_status = false; - RT_TRACE(COMP_FIRMWARE, "Unknown firware status"); + RT_TRACE(COMP_FIRMWARE, "Unknown firmware status"); break; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c index 3e705ef..9676c59 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_phy.c @@ -689,7 +689,7 @@ void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel) case RF_8258: break; default: - RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", + RT_TRACE(COMP_ERR, "unknown rf chip in function %s()\n", __func__); break; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h index d5de279..970298b 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h +++ b/drivers/staging/rtl8192e/rtl8192e/r819xE_phyreg.h @@ -306,7 +306,7 @@ #define bRFStart 0x0000f000 #define bBBStart 0x000000f0 #define bBBCCKStart 0x0000000f -/* Reg)x814 */ +/* Reg x814 */ #define bPAEnd 0xf #define bTREnd 0x0f000000 #define bRFEnd 0x000f0000 @@ -844,7 +844,7 @@ #define bRTL8258_RxLPFBW 0xc00 #define bRTL8258_RSSILPFBW 0xc0 -/* byte endable for sb_write */ +/* byte enable for sb_write */ #define bByte0 0x1 #define bByte1 0x2 #define bByte2 0x4 diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 71adb6b..4f602b2 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -1025,7 +1025,7 @@ static int rtl8192_sta_down(struct net_device *dev, bool shutdownrf) break; } RT_TRACE(COMP_DBG, "===>%s():RF is in progress, need to wait " - "until rf chang is done.\n", __func__); + "until rf change is done.\n", __func__); mdelay(1); RFInProgressTimeOut++; spin_lock_irqsave(&priv->rf_ps_lock, flags); @@ -1211,7 +1211,7 @@ static void rtl8192_init_priv_variable(struct net_device *dev) priv->AcmControl = 0; priv->pFirmware = vzalloc(sizeof(struct rt_firmware)); if (!priv->pFirmware) - printk(KERN_ERR "rtl8193e: Unable to allocate space " + printk(KERN_ERR "rtl8192e: Unable to allocate space " "for firmware\n"); skb_queue_head_init(&priv->rx_queue); @@ -2024,10 +2024,10 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) stype = WLAN_FC_GET_STYPE(fc); pda_addr = header->addr1; - if (is_multicast_ether_addr(pda_addr)) - multi_addr = true; - else if (is_broadcast_ether_addr(pda_addr)) + if (is_broadcast_ether_addr(pda_addr)) broad_addr = true; + else if (is_multicast_ether_addr(pda_addr)) + multi_addr = true; else uni_addr = true; @@ -2358,8 +2358,7 @@ static void rtl8192_rx_normal(struct net_device *dev) stats.RxBufShift); skb_trim(skb, skb->len - 4/*sCrcLng*/); rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data; - if (!is_broadcast_ether_addr(rtllib_hdr->addr1) && - !is_multicast_ether_addr(rtllib_hdr->addr1)) { + if (!is_multicast_ether_addr(rtllib_hdr->addr1)) { /* unicast packet */ unicast_packet = true; } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h index 2a2519c..320d5fc 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.h +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.h @@ -353,7 +353,6 @@ struct rt_stats { unsigned long rxrdu; unsigned long rxok; unsigned long rxframgment; - unsigned long rxcmdpkt[8]; unsigned long rxurberr; unsigned long rxstaterr; unsigned long rxdatacrcerr; @@ -944,7 +943,7 @@ struct r8192_priv { bool bfsync_processing; u32 rate_record; u32 rateCountDiffRecord; - u32 ContiuneDiffCount; + u32 ContinueDiffCount; bool bswitch_fsync; u8 framesync; u32 framesyncC34; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index f026b71..481b1e4 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -493,7 +493,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) if (priv->bResetInProgress) { RT_TRACE(COMP_POWER_TRACKING, - "we are in slient reset progress, so return\n"); + "we are in silent reset progress, so return\n"); write_nic_byte(dev, Pw_Track_Flag, 0); write_nic_byte(dev, FW_Busy_Flag, 0); return; @@ -2615,22 +2615,22 @@ void dm_fsync_timer_callback(unsigned long data) rate_count_diff; if (DiffNum >= priv->rtllib->fsync_seconddiff_ratethreshold) - priv->ContiuneDiffCount++; + priv->ContinueDiffCount++; else - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; - if (priv->ContiuneDiffCount >= 2) { + if (priv->ContinueDiffCount >= 2) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } } else { - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } if (rate_count_diff <= priv->rtllib->fsync_firstdiff_ratethreshold) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } priv->rate_record = rate_count; priv->rateCountDiffRecord = rate_count_diff; @@ -2677,10 +2677,10 @@ void dm_fsync_timer_callback(unsigned long data) write_nic_byte(dev, 0xC36, 0x5c); write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); } - RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d " "bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync); @@ -2723,7 +2723,7 @@ static void dm_EndSWFsync(struct net_device *dev) write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); } @@ -2735,7 +2735,7 @@ static void dm_StartSWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM, "%s\n", __func__); priv->rate_record = 0; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c index 4e93669..778d7ba 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_wx.c @@ -1322,9 +1322,9 @@ static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) struct iw_handler_def r8192_wx_handlers_def = { .standard = r8192_wx_handlers, - .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(r8192_wx_handlers), .private = r8192_private_handler, - .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), + .num_private = ARRAY_SIZE(r8192_private_handler), .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), .get_wireless_stats = r8192_get_wireless_stats, diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c index 711a096..658e875 100644 --- a/drivers/staging/rtl8192e/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -310,7 +310,7 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) { u8 UP = 0; - if (is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) { + if (is_multicast_ether_addr(Addr)) { RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or " "Multicast\n"); return false; diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index e26aec8..d7460ae 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -169,7 +169,7 @@ struct cb_desc { u8 nStuckCount; - /* Tx Firmware Relaged flags (10-11)*/ + /* Tx Firmware Related flags (10-11)*/ u8 bCTSEnable:1; u8 bRTSEnable:1; u8 bUseShortGI:1; @@ -1690,7 +1690,7 @@ enum rtllib_state { /* the association procedure is sending AUTH request*/ RTLLIB_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ RTLLIB_ASSOCIATING_AUTHENTICATED, @@ -2409,7 +2409,7 @@ struct rtllib_device { /* used instead of hard_start_xmit (not softmac_hard_start_xmit) * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set * then also management frames are sent via this callback. * This function can't sleep. */ @@ -2422,12 +2422,12 @@ struct rtllib_device { */ void (*data_hard_stop)(struct net_device *dev); - /* OK this is complementar to data_poll_hard_stop */ + /* OK this is complementing to data_poll_hard_stop */ void (*data_hard_resume)(struct net_device *dev); /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure - * the radio has been swithced before return. + * the radio has been switched before return. */ void (*set_chan)(struct net_device *dev, short ch); @@ -2438,7 +2438,7 @@ struct rtllib_device { * The syncro version is similar to the start_scan but * does not return until all channels has been scanned. * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode + * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. * the fucntion stop_scan should stop both the syncro and @@ -2481,7 +2481,7 @@ struct rtllib_device { struct rtllib_network *network); - /* check whether Tx hw resouce available */ + /* check whether Tx hw resource available */ short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); short (*get_nic_desc_num)(struct net_device *dev, int queue_index); void (*SetBWModeHandler)(struct net_device *dev, @@ -2543,10 +2543,10 @@ struct rtllib_device { /* Generate probe requests */ #define IEEE_SOFTMAC_PROBERQ (1<<4) -/* Generate respones to probe requests */ +/* Generate response to probe requests */ #define IEEE_SOFTMAC_PROBERS (1<<5) -/* The ieee802.11 stack will manages the netif queue +/* The ieee802.11 stack will manage the netif queue * wake/stop for the driver, taking care of 802.11 * fragmentation. See softmac.c for details. */ #define IEEE_SOFTMAC_TX_QUEUE (1<<7) diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 13979b5..8b8a5c6 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -496,7 +496,7 @@ void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prx memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); } - /* Indicat the packets to upper layer */ + /* Indicate the packets to upper layer */ if (sub_skb) { stats->rx_packets++; stats->rx_bytes += sub_skb->len; @@ -1000,7 +1000,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, return -1; /* {broad,multi}cast packets to our BSS go through */ - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) { + if (is_multicast_ether_addr(dst)) { if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) return -1; } @@ -1233,7 +1233,7 @@ static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, if (is_multicast_ether_addr(dst)) ieee->stats.multicast++; - /* Indicat the packets to upper layer */ + /* Indicate the packets to upper layer */ memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); sub_skb->protocol = eth_type_trans(sub_skb, dev); sub_skb->dev = dev; @@ -1269,7 +1269,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, sc = le16_to_cpu(hdr->seq_ctl); /*Filter pkt not to me*/ - multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1); + multicast = is_multicast_ether_addr(hdr->addr1); unicast = !multicast; if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) { if (ieee->bNetPromiscuousMode) @@ -1350,7 +1350,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, /* Get TS for Rx Reorder */ hdr = (struct rtllib_hdr_4addr *) skb->data; if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1) + && !is_multicast_ether_addr(hdr->addr1) && (!bToOtherSTA)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index c5a15db..a21b4d9 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -31,7 +31,7 @@ short rtllib_is_shortslot(const struct rtllib_network *net) return net->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME; } -/* returns the total length needed for pleacing the RATE MFIE +/* returns the total length needed for placing the RATE MFIE * tag and the EXTENDED RATE MFIE tag if needed. * It encludes two bytes per tag for the tag itself and its len */ @@ -49,7 +49,7 @@ static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee) return rate_len; } -/* pleace the MFIE rate, tag to the memory (double) poined. +/* place the MFIE rate, tag to the memory (double) pointed. * Then it updates the pointer so that * it points after the new MFIE tag added. */ @@ -557,7 +557,7 @@ void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh) * new network events, despite for updating the net list, * but we are temporarly 'unlinked' as the driver shall * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check + * So the only situation in which are interested is to check * if the state become LINKED because of the #1 situation */ @@ -1681,7 +1681,7 @@ inline void rtllib_softmac_new_net(struct rtllib_device *ieee, /* if the user set the AP check if match. * if the network does not broadcast essid we check the - * user supplyed ANY essid + * user supplied ANY essid * if the network does broadcast and the user does not set * essid it is OK * if the network does broadcast and the user did set essid @@ -2444,16 +2444,16 @@ inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, /* following are for a simplier TX queue management. * Instead of using netif_[stop/wake]_queue the driver - * will uses these two function (plus a reset one), that - * will internally uses the kernel netif_* and takes + * will use these two functions (plus a reset one), that + * will internally use the kernel netif_* and takes * care of the ieee802.11 fragmentation. * So the driver receives a fragment per time and might - * call the stop function when it want without take care - * to have enought room to TX an entire packet. - * This might be useful if each fragment need it's own + * call the stop function when it wants to not + * have enough room to TX an entire packet. + * This might be useful if each fragment needs it's own * descriptor, thus just keep a total free memory > than - * the max fragmentation treshold is not enought.. If the - * ieee802.11 stack passed a TXB struct then you needed + * the max fragmentation threshold is not enough.. If the + * ieee802.11 stack passed a TXB struct then you need * to keep N free descriptors where * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD * In this way you need just one and the 802.11 stack @@ -2696,15 +2696,15 @@ static void rtllib_start_ibss_wq(void *data) rtllib_softmac_check_all_nets(ieee); - /* if not then the state is not linked. Maybe the user swithced to + /* if not then the state is not linked. Maybe the user switched to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no * time to scan all the chans..) or we have just run up the iface * after setting ad-hoc mode. So we have to give another try.. * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tryed to associate when + * (in bss mode we had to make sure no-one tried to associate when * we had just checked the ieee->state and we was going to start the - * scan) beacause in ibss mode the rtllib_new_net function, when + * scan) because in ibss mode the rtllib_new_net function, when * finds a good net, just set the ieee->state to RTLLIB_LINKED, * so, at worst, we waste a bit of time to initiate an unneeded syncro * scan, that will stop at the first round because it sees the state @@ -2819,7 +2819,7 @@ void rtllib_start_bss(struct rtllib_device *ieee) /* ensure no-one start an associating process (thus setting * the ieee->state to rtllib_ASSOCIATING) while we - * have just cheked it and we are going to enable scan. + * have just checked it and we are going to enable scan. * The rtllib_new_net function is always called with * lock held (from both rtllib_softmac_check_all_nets and * the rx path), so we cannot be in the middle of such function @@ -2872,7 +2872,7 @@ static void rtllib_associate_retry_wq(void *data) /* until we do not set the state to RTLLIB_NOLINK * there are no possibility to have someone else trying - * to start an association procdure (we get here with + * to start an association procedure (we get here with * ieee->state = RTLLIB_ASSOCIATING). * When we set the state to RTLLIB_NOLINK it is possible * that the RX path run an attempt to associate, but @@ -3679,8 +3679,7 @@ void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, RemovePeerTS(rtllib, asSta); - - if (memcpy(rtllib->current_network.bssid, asSta, 6) == NULL) { + if (memcmp(rtllib->current_network.bssid, asSta, 6) == 0) { rtllib->state = RTLLIB_NOLINK; for (i = 0; i < 6; i++) diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index 1523bc7..1bb6b52e 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -479,7 +479,7 @@ int rtllib_wx_set_essid(struct rtllib_device *ieee, /* this is just to be sure that the GET wx callback - * has consisten infos. not needed otherwise + * has consistent infos. not needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); @@ -575,7 +575,7 @@ int rtllib_wx_set_power(struct rtllib_device *ieee, if ((!ieee->sta_wake_up) || (!ieee->enter_sleep_state) || (!ieee->ps_is_queue_empty)) { - RTLLIB_DEBUG(RTLLIB_DL_ERR, "%s(): PS mode is tryied to be use " + RTLLIB_DEBUG(RTLLIB_DL_ERR, "%s(): PS mode is tried to be use " "but driver missed a callback\n\n", __func__); return -1; } diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index f451bfc..42900ee 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -59,7 +59,7 @@ 802.11 Data Frame -802.11 frame_contorl for data frames - 2 bytes +802.11 frame_control for data frames - 2 bytes ,-----------------------------------------------------------------------------------------. bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| @@ -296,8 +296,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, return; if (!IsQoSDataFrame(skb->data)) return; - if (is_multicast_ether_addr(hdr->addr1) || - is_broadcast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1)) return; if (tcb_desc->bdhcp || ieee->CntAfterLink < 2) @@ -515,7 +514,7 @@ u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, { u16 seqnum = 0; - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + if (is_multicast_ether_addr(dst)) return 0; if (IsQoSDataFrame(skb->data)) { struct tx_ts_record *pTS = NULL; @@ -576,7 +575,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&ieee->lock, flags); - /* If there is no driver handler to take the TXB, dont' bother + /* If there is no driver handler to take the TXB, don't bother * creating it... */ if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || @@ -698,8 +697,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) ETH_ALEN); } - bIsMulticast = is_broadcast_ether_addr(header.addr1) || - is_multicast_ether_addr(header.addr1); + bIsMulticast = is_multicast_ether_addr(header.addr1); header.frame_ctl = cpu_to_le16(fc); @@ -738,7 +736,7 @@ int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) bytes_per_frag -= RTLLIB_FCS_LEN; - /* Each fragment may need to have room for encryptiong + /* Each fragment may need to have room for encrypting * pre/postfix */ if (encrypt) { bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index c27ff7e..c7e8d4d8 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -88,7 +88,7 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, } /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; - for (i = 0; i < (sizeof(rtllib_modes)/sizeof(rtllib_modes[0])); i++) { + for (i = 0; i < ARRAY_SIZE(rtllib_modes); i++) { if (network->mode&(1<<i)) { sprintf(pname, rtllib_modes[i].mode_string, rtllib_modes[i].mode_size); @@ -408,7 +408,7 @@ int rtllib_wx_set_encode(struct rtllib_device *ieee, (*crypt)->priv); sec.flags |= (1 << key); /* This ensures a key will be activated if no key is - * explicitely set */ + * explicitly set */ if (key == sec.active_key) sec.flags |= SEC_ACTIVE_KEY; ieee->crypt_info.tx_keyidx = key; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index e3d47bc..82d4bf6 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -161,7 +161,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) if (ieee->pHTInfo == NULL) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); - return NULL; + goto failed; } HTUpdateDefaultSetting(ieee); HTInitializeHTInfo(ieee); //may move to other place. diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index be2a28c..e3cf7a4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -671,7 +671,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee, index = 1; } else { /* Current packet is going to be inserted into pending list.*/ - //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__); + //IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to ordered list\n",__FUNCTION__); if(!list_empty(&ieee->RxReorder_Unused_List)) { pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List); list_del_init(&pReorderEntry->List); @@ -1285,7 +1285,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, */ //added by amy for reorder if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) + && !is_multicast_ether_addr(hdr->addr1)) { TID = Frame_QoSTID(skb->data); SeqNum = WLAN_GET_SEQ_SEQ(sc); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index c2ab5fa..f6ff8cf 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2062,7 +2062,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, } }else{ ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); + IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode); ieee80211_associate_abort(ieee); } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 59c45a5..3f5ceeb 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -314,7 +314,7 @@ void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* s if (!IsQoSDataFrame(skb->data)) return; - if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1)) return; //check packet and mode later #ifdef TO_DO_LIST @@ -575,7 +575,7 @@ void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_des void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst) { - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + if (is_multicast_ether_addr(dst)) return; if (IsQoSDataFrame(skb->data)) //we deal qos data only { @@ -693,8 +693,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) /* Determine fragmentation size based on destination (multicast * and broadcast are not fragmented) */ - if (is_multicast_ether_addr(header.addr1) || - is_broadcast_ether_addr(header.addr1)) { + if (is_multicast_ether_addr(header.addr1)) { frag_size = MAX_FRAG_THRESHOLD; qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; } diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c index 957ce4e..06a9824 100644 --- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c +++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c @@ -350,7 +350,7 @@ bool GetTs( // We do not build any TS for Broadcast or Multicast stream. // So reject these kinds of search here. // - if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) + if (is_multicast_ether_addr(Addr)) { IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); return false; diff --git a/drivers/staging/rtl8192u/r8180_93cx6.c b/drivers/staging/rtl8192u/r8180_93cx6.c index 8878cfe..3c515b7 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.c +++ b/drivers/staging/rtl8192u/r8180_93cx6.c @@ -14,7 +14,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h index fb3ac97..5cea51e 100644 --- a/drivers/staging/rtl8192u/r8180_93cx6.h +++ b/drivers/staging/rtl8192u/r8180_93cx6.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thank the Authors of such projects and the Ndiswrapper project Authors. */ /*This files contains card eeprom (93c46 or 93c56) programming routines*/ diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 9b81f26..57e3383 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -11,7 +11,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ @@ -98,7 +98,7 @@ do { if(rt_global_debug_component & component) \ #define COMP_INIT BIT2 // during driver initialization / halt / reset. -#define COMP_RECV BIT3 // Reveive part data path. +#define COMP_RECV BIT3 // Receive data path. #define COMP_SEND BIT4 // Send part path. #define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02. #define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related. @@ -322,7 +322,7 @@ typedef struct _tx_fwinfo_819x_usb { u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. u8 STBC:2; u8 AllowAggregation:1; - u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate + u8 RtsHT:1; //Interpret RtsRate field as high throughput data rate u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS u8 RtsBandwidth:1; // This is used for HT MCS rate only. u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. @@ -610,7 +610,6 @@ typedef struct Stats // unsigned long rxnopointer; unsigned long rxok; unsigned long rxframgment; - unsigned long rxcmdpkt[4]; //08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query unsigned long rxurberr; unsigned long rxstaterr; unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa @@ -1117,7 +1116,7 @@ typedef struct r8192_priv bool bfsync_processing; // 500ms Fsync timer is active or not u32 rate_record; u32 rateCountDiffRecord; - u32 ContiuneDiffCount; + u32 ContinueDiffCount; bool bswitch_fsync; u8 framesync; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 9c00865..5981d66 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -203,7 +203,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) { Dot11d_Init(ieee); ieee->bGlobalDomain = false; - //acturally 8225 & 8256 rf chip only support B,G,24N mode + //actually 8225 & 8256 rf chips only support B,G,24N mode if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256)) { min_chan = 1; @@ -1103,7 +1103,7 @@ inline u16 rtl8192_rate2rate(short rate) } -/* The protype of rx_isr has changed since one verion of Linux Kernel */ +/* The prototype of rx_isr has changed since one version of Linux Kernel */ static void rtl8192_rx_isr(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; @@ -1476,7 +1476,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb) if(tcb_desc->queue_index != TXCMD_QUEUE) { if(tx_urb->status == 0) { dev->trans_start = jiffies; - // As act as station mode, destion shall be unicast address. + // Act as station mode, destination shall be unicast address. //priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom); //priv->ieee80211->stats.tx_packets++; priv->stats.txoktotal++; @@ -1522,13 +1522,13 @@ static void rtl8192_tx_isr(struct urb *tx_urb) else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\ (!(priv->ieee80211->queue_stop))) { // Tx Driver Aggregation process - /* The driver will aggregation the packets according to the following stets + /* The driver will aggregation the packets according to the following stats * 1. check whether there's tx irq available, for it's a completion return * function, it should contain enough tx irq; - * 2. check pakcet type; + * 2. check packet type; * 3. initialize sendlist, check whether the to-be send packet no greater than 1 - * 4. aggregation the packets, and fill firmware info and tx desc to it, etc. - * 5. check whehter the packet could be sent, otherwise just insert to wait head + * 4. aggregates the packets, and fill firmware info and tx desc into it, etc. + * 5. check whether the packet could be sent, otherwise just insert into wait head * */ skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]); if(!check_nic_enough_desc(dev, queue_index)) { @@ -2447,7 +2447,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, return 0; } -/* handle manage frame frame beacon and probe response */ +/* handle and manage frame from beacon and probe response */ static int rtl8192_handle_beacon(struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network) @@ -2625,7 +2625,7 @@ bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev) void rtl8192_refresh_supportrate(struct r8192_priv* priv) { struct ieee80211_device* ieee = priv->ieee80211; - //we donot consider set support rate for ABG mode, only HT MCS rate is set here. + //we do not consider set support rate for ABG mode, only HT MCS rate is set here. if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) { memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16); @@ -2780,10 +2780,10 @@ static void rtl8192_init_priv_variable(struct net_device* dev) priv->TransmitConfig = // TCR_DurProcMode | //for RTL8185B, duration setting by HW //? TCR_DISReqQsize | - (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reservied. + (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)| // Max DMA Burst Size per Tx DMA Burst, 7: reserved. (priv->ShortRetryLimit<<TCR_SRL_OFFSET)| // Short retry limit (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit - (false ? TCR_SAT: 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them + (false ? TCR_SAT: 0); // FALSE: HW provides PLCP length and LENGEXT, TRUE: SW provides them #ifdef TO_DO_LIST if(Adapter->bInHctTest) pHalData->ReceiveConfig = pHalData->CSMethod | @@ -3437,7 +3437,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) { // User disable RF via registry. RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n")); MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW); - // Those action will be discard in MgntActSet_RF_State because off the same state + // Those actions will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -3458,7 +3458,7 @@ if(Adapter->ResetProgress == RESET_TYPE_NORESET) if(pHalData->eRFPowerState == eRfOff) { MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason); - // Those action will be discard in MgntActSet_RF_State because off the same state + // Those actions will be discard in MgntActSet_RF_State because of the same state for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++) PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0); } @@ -3586,7 +3586,7 @@ TxCheckStuck(struct net_device *dev) //unsigned long flags; // - // Decide Stuch threshold according to current power save mode + // Decide such threshold according to current power save mode // // RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n"); @@ -3745,7 +3745,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev) // Driver should not check RX stuck in IBSS mode because it is required to // set Check BSSID in order to send beacon, however, if check BSSID is - // set, STA cannot hear any packet a all. Emily, 2008.04.12 + // set, STA cannot hear any packet at all. Emily, 2008.04.12 RxResetType = RxCheckStuck(dev); } if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL) @@ -3962,7 +3962,7 @@ RESET_START: up(&priv->wx_sem); RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__); //rtl8192_irq_disable(dev); - RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__); + RT_TRACE(COMP_RESET,"%s():===========>start up the driver\n",__FUNCTION__); reset_status = _rtl8192_up(dev); RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__); @@ -4155,7 +4155,7 @@ extern void rtl819x_watchdog_wqcallback(struct work_struct *work) void watch_dog_timer_callback(unsigned long data) { struct r8192_priv *priv = ieee80211_priv((struct net_device *) data); - //printk("===============>watch_dog timer\n"); + //printk("===============>watch_dog timer\n"); queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0); mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); } @@ -4170,7 +4170,7 @@ int _rtl8192_up(struct net_device *dev) init_status = rtl8192_adapter_start(dev); if(!init_status) { - RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__); + RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization failed!\n", __FUNCTION__); priv->up=priv->ieee80211->ieee_up = 0; return -EAGAIN; } @@ -4256,7 +4256,7 @@ int rtl8192_down(struct net_device *dev) skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]); } - //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt + //as cancel_delayed_work will del work->timer, so if work is not defined as struct delayed_work, it will corrupt // flush_scheduled_work(); rtl8192_cancel_deferred_work(priv); deinit_hal_dm(dev); @@ -4516,7 +4516,7 @@ u8 HwRateToMRate90(bool bIsHT, u8 rate) /** * Function: UpdateRxPktTimeStamp - * Overview: Recored down the TSF time stamp when receiving a packet + * Overview: Record the TSF time stamp when receiving a packet * * Input: * PADAPTER Adapter @@ -4556,10 +4556,10 @@ long rtl819x_translate_todbm(u8 signal_strength_index )// 0-100 index. } -/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to +/* 2008/01/22 MH We can not declare RSSI/EVM total value of sliding window to be a local static. Otherwise, it may increase when we return from S3/S4. The - value will be kept in memory or disk. We must delcare the value in adapter - and it will be reinitialized when return from S3/S4. */ + value will be kept in memory or disk. Declare the value in the adaptor + and it will be reinitialized when returned from S3/S4. */ void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats) { bool bcheck = false; @@ -5091,8 +5091,8 @@ static void rtl8192_query_rxphystatus( tmp_rxevm = pofdm_buf->rxevm_X[i]; rx_evmX = (char)(tmp_rxevm); - // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment - // fill most significant bit to "zero" when doing shifting operation which may change a negative + // Do not use shift operation like "rx_evmX >>= 1" because the compiler of free build environment + // will set the most significant bit to "zero" when doing shifting operation which may change a negative // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. rx_evmX /= 2; //dbm @@ -5171,7 +5171,7 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, type = WLAN_FC_GET_TYPE(fc); praddr = hdr->addr1; - /* Check if the received packet is acceptabe. */ + /* Check if the received packet is acceptable. */ bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) && (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); @@ -5211,7 +5211,7 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb, /** * Function: UpdateReceivedRateHistogramStatistics -* Overview: Recored down the received data rate +* Overview: Record the received data rate * * Input: * struct net_device *dev @@ -5401,7 +5401,7 @@ void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, } #ifdef USB_RX_AGGREGATION_SUPPORT - /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */ + /* for the rx aggregated sub frame, the redundant space truly contained in the packet */ if(bIsRxAggrSubframe) { skb_pull(skb, 8); } @@ -5480,7 +5480,7 @@ void rtl8192_rx_nomal(struct sk_buff* skb) PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false); } #endif - /* Process the MPDU recevied */ + /* Process the MPDU received */ skb_trim(skb, skb->len - 4/*sCrcLng*/); rx_pkt_len = skb->len; @@ -5538,7 +5538,7 @@ void rtl8192_rx_nomal(struct sk_buff* skb) if(PacketLength > agg_skb->len) { break; } - /* Process the MPDU recevied */ + /* Process the MPDU received */ skb = dev_alloc_skb(PacketLength); memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength); skb_trim(skb, skb->len - 4/*sCrcLng*/); diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c index 2dde9fa..cd8dc85 100644 --- a/drivers/staging/rtl8192u/r8192U_dm.c +++ b/drivers/staging/rtl8192u/r8192U_dm.c @@ -38,7 +38,7 @@ static u32 edca_setting_UL[HT_IOT_PEER_MAX] = /*------------------------Define global variable-----------------------------*/ // Debug variable ? dig_t dm_digtable; -// Store current shoftware write register content for MAC PHY. +// Store current software write register content for MAC PHY. u8 dm_shadow[16][256] = {{0}}; // For Dynamic Rx Path Selection by Signal Strength DRxPathSel DM_RxPathSelTable; @@ -119,7 +119,7 @@ static void dm_pd_th(struct net_device *dev); static void dm_cs_ratio(struct net_device *dev); static void dm_init_ctstoself(struct net_device *dev); -// DM --> EDCA turboe mode control +// DM --> EDCA turbo mode control static void dm_check_edca_turbo(struct net_device *dev); // DM --> HW RF control @@ -348,7 +348,7 @@ extern void init_rate_adaptive(struct net_device * dev) * * Revised History: * When Who Remark - * 05/26/08 amy Create version 0 proting from windows code. + * 05/26/08 amy Create version 0 porting from windows code. * *---------------------------------------------------------------------------*/ static void dm_check_rate_adaptive(struct net_device * dev) @@ -543,7 +543,7 @@ static u32 OFDMSwingTable[OFDM_Table_Length] = { 0x5a400169, // 3, +3db 0x50800142, // 4, +2db 0x47c0011f, // 5, +1db - 0x40000100, // 6, +0db ===> default, upper for higher temprature, lower for low temprature + 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature 0x390000e4, // 7, -1db 0x32c000cb, // 8, -2db 0x2d4000b5, // 9, -3db @@ -678,7 +678,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev) { write_nic_byte(dev, 0x1ba, 0); viviflag = FALSE; - RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); + RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n"); for(k = 0;k < 5; k++) tmp_report[k] = 0; break; @@ -864,14 +864,14 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA); if(tmpRegA < 3 || tmpRegA > 13) return; - if(tmpRegA >= 12) // if over 12, TP will be bad when high temprature + if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature tmpRegA = 12; RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA); priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion - //Get current RF-A temprature index - if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temprature + //Get current RF-A temperature index + if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature { tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); tmpCCK40Mindex = tmpCCK20Mindex - 6; @@ -885,7 +885,7 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev) else { tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); - if(tmpval >= 6) // higher temprature + if(tmpval >= 6) // higher temperature tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB else tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; @@ -1457,9 +1457,9 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); - // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism + // Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w - // 3-wire by driver cause RF goes into wrong state. + // 3-wire by driver causes RF to go into a wrong state. if(priv->ieee80211->FwRWRF) priv->btxpower_tracking = TRUE; else @@ -1520,7 +1520,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) if(!TM_Trigger) { - //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash + //Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash //actually write reg0x02 bit1=0, then bit1=1. //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n"); rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); @@ -1744,7 +1744,7 @@ extern void dm_restore_dynamic_mechanism_state(struct net_device *dev) write_nic_dword(dev, RATR0, ratr_value); write_nic_byte(dev, UFWP, 1); } - //Resore TX Power Tracking Index + //Restore TX Power Tracking Index if(priv->btxpower_trackingInit && priv->btxpower_tracking){ dm_txpower_reset_recovery(dev); } @@ -2031,7 +2031,7 @@ static void dm_dig_init(struct net_device *dev) dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig dm_digtable.dig_algorithm_switch = 0; - /* 2007/10/04 MH Define init gain threshol. */ + /* 2007/10/04 MH Define init gain threshold. */ dm_digtable.dig_state = DM_STA_DIG_MAX; dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; dm_digtable.initialgain_lowerbound_state = false; @@ -2097,7 +2097,7 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi( return; //DbgPrint("Dig by Sw Rssi \n"); - if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig. + if(dm_digtable.dig_algorithm_switch) // if switched algorithm, we have to disable FW Dig. fw_dig = 0; if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled {// FW DIG Off @@ -2160,8 +2160,8 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d", pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh, DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/ - /* 1. When RSSI decrease, We have to judge if it is smaller than a treshold - and then execute below step. */ + /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold + and then execute the step below. */ if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) { /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters @@ -2220,8 +2220,8 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( } - /* 2. When RSSI increase, We have to judge if it is larger than a treshold - and then execute below step. */ + /* 2. When RSSI increase, We have to judge if it is larger than a threshold + and then execute the step below. */ if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) ) { u8 reset_flag = 0; @@ -2329,7 +2329,7 @@ static void dm_ctrl_initgain_byrssi_highpwr( } /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if - it is larger than a treshold and then execute below step. */ + it is larger than a threshold and then execute the step below. */ // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { @@ -2841,8 +2841,8 @@ static void dm_check_rfctrl_gpio(struct net_device * dev) { //struct r8192_priv *priv = ieee80211_priv(dev); - // Walk around for DTM test, we will not enable HW - radio on/off because r/w - // page 1 register before Lextra bus is enabled cause system fails when resuming + // Work around for DTM test, we will not enable HW - radio on/off because r/w + // page 1 register before extra bus is enabled causing system failures when resuming // from S4. 20080218, Emily // Stop to execute workitem to prevent S3/S4 bug. @@ -3377,30 +3377,30 @@ extern void dm_fsync_timer_callback(unsigned long data) { u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; - // Contiune count + // Continue count if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) - priv->ContiuneDiffCount++; + priv->ContinueDiffCount++; else - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; - // Contiune count over - if(priv->ContiuneDiffCount >=2) + // Continue count over + if(priv->ContinueDiffCount >=2) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } } else { - // Stop contiune count - priv->ContiuneDiffCount = 0; + // Stop the continued count + priv->ContinueDiffCount = 0; } //If Count diff <= FsyncRateCountThreshold if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) { bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; } priv->rate_record = rate_count; priv->rateCountDiffRecord = rate_count_diff; @@ -3468,14 +3468,14 @@ extern void dm_fsync_timer_callback(unsigned long data) #endif write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; #ifdef RTL8190P write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd); #else write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); #endif } - RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); } @@ -3507,7 +3507,7 @@ static void dm_EndSWFsync(struct net_device *dev) write_nic_byte(dev, 0xC3e, 0x96); } - priv->ContiuneDiffCount = 0; + priv->ContinueDiffCount = 0; #ifndef RTL8190P write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); #endif @@ -3523,8 +3523,8 @@ static void dm_StartSWFsync(struct net_device *dev) RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); // Initial rate record to zero, start to record. priv->rate_record = 0; - // Initial contiune diff count to zero, start to record. - priv->ContiuneDiffCount = 0; + // Initialize continue diff count to zero, start to record. + priv->ContinueDiffCount = 0; priv->rateCountDiffRecord = 0; priv->bswitch_fsync = false; @@ -3875,7 +3875,7 @@ static void dm_send_rssi_tofw(struct net_device *dev) // If we test chariot, we should stop the TX command ? // Because 92E will always silent reset when we send tx command. We use register - // 0x1e0(byte) to botify driver. + // 0x1e0(byte) to notify driver. write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); return; tx_cmd.Op = TXCMD_SET_RX_RSSI; diff --git a/drivers/staging/rtl8192u/r8192U_hw.h b/drivers/staging/rtl8192u/r8192U_hw.h index e89aaf7..1bfe871 100644 --- a/drivers/staging/rtl8192u/r8192U_hw.h +++ b/drivers/staging/rtl8192u/r8192U_hw.h @@ -10,7 +10,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index f6408f9..71f2d23 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -13,7 +13,7 @@ Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - We want to tanks the Authors of those projects and the Ndiswrapper + We want to thank the Authors of those projects and the Ndiswrapper project Authors. */ @@ -256,7 +256,7 @@ static int r8192_wx_get_ap_status(struct net_device *dev, //count the length of input ssid for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++); - //search for the correspoding info which is received + //search for the corresponding info which is received list_for_each_entry(target, &ieee->network_list, list) { if ( (target->ssid_len == name_len) && (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){ @@ -419,7 +419,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 20 + -98; range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ @@ -1047,7 +1047,7 @@ static iw_handler r8192_wx_handlers[] = #else NULL, #endif - dummy, /* SIOCGIWAPLIST -- depricated */ + dummy, /* SIOCGIWAPLIST -- deprecated */ r8192_wx_set_scan, /* SIOCSIWSCAN */ r8192_wx_get_scan, /* SIOCGIWSCAN */ r8192_wx_set_essid, /* SIOCSIWESSID */ @@ -1211,9 +1211,9 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) struct iw_handler_def r8192_wx_handlers_def={ .standard = r8192_wx_handlers, - .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(r8192_wx_handlers), .private = r8192_private_handler, - .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), + .num_private = ARRAY_SIZE(r8192_private_handler), .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), #if WIRELESS_EXT >= 17 .get_wireless_stats = r8192_get_wireless_stats, diff --git a/drivers/staging/rtl8192u/r8192U_wx.h b/drivers/staging/rtl8192u/r8192U_wx.h index f4cf280..9f6b105 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.h +++ b/drivers/staging/rtl8192u/r8192U_wx.h @@ -7,7 +7,7 @@ Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. + We want to thank the Authors of such projects and the Ndiswrapper project Authors. */ /* this file (will) contains wireless extension handlers*/ diff --git a/drivers/staging/rtl8192u/r819xU_HTType.h b/drivers/staging/rtl8192u/r819xU_HTType.h index 2ac4216..e07f8b1 100644 --- a/drivers/staging/rtl8192u/r819xU_HTType.h +++ b/drivers/staging/rtl8192u/r819xU_HTType.h @@ -211,7 +211,7 @@ typedef struct _RT_HIGH_THROUGHPUT{ u8 bEnableHT; u8 bCurrentHTSupport; - u8 bRegBW40MHz; // Tx 40MHz channel capablity + u8 bRegBW40MHz; // Tx 40MHz channel capability u8 bCurBW40MHz; // Tx 40MHz channel capability u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c index 0cb28c7..a8a6dc2 100644 --- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c +++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c @@ -157,7 +157,7 @@ SendTxCommandPacket( seg_ptr = skb_put(skb, buffer_len); /* * Transform from little endian to big endian - * and pending zero + * and pending zero */ memcpy(seg_ptr,codevirtualaddress,buffer_len); tcb_desc->txbuf_size= (u16)buffer_len; @@ -697,7 +697,6 @@ cmpk_message_handle_rx( struct ieee80211_rx_stats *pstats) { // u32 debug_level = DBG_LOUD; - struct r8192_priv *priv = ieee80211_priv(dev); int total_length; u8 cmd_length, exe_cnt = 0; u8 element_id; @@ -719,15 +718,15 @@ cmpk_message_handle_rx( /* 2. Read virtual address from RFD. */ pcmd_buff = pstats->virtual_address; - /* 3. Read command pakcet element id and length. */ + /* 3. Read command packet element id and length. */ element_id = pcmd_buff[0]; /*RT_TRACE(COMP_SEND, DebugLevel, ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ - /* 4. Check every received command packet conent according to different + /* 4. Check every received command packet content according to different element type. Because FW may aggregate RX command packet to minimize transmit time between DRV and FW.*/ - // Add a counter to prevent to locked in the loop too long + // Add a counter to prevent the lock in the loop from being held too long while (total_length > 0 || exe_cnt++ >100) { /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ @@ -779,9 +778,6 @@ cmpk_message_handle_rx( // 2007/01/22 MH Add to display tx statistic. //cmpk_DisplayTxStatistic(pAdapter); - /* 2007/03/09 MH Collect sidderent cmd element pkt num. */ - priv->stats.rxcmdpkt[element_id]++; - total_length -= cmd_length; pcmd_buff += cmd_length; } /* while (total_length > 0) */ diff --git a/drivers/staging/rtl8192u/r819xU_firmware.c b/drivers/staging/rtl8192u/r819xU_firmware.c index 4bb5fff..b12d190 100644 --- a/drivers/staging/rtl8192u/r819xU_firmware.c +++ b/drivers/staging/rtl8192u/r819xU_firmware.c @@ -275,11 +275,11 @@ bool init_firmware(struct net_device *dev) /* * Download boot, main, and data image for System reset. - * Download data image for firmware reseta + * Download data image for firmware reset */ for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) { /* - * Open Image file, and map file to contineous memory if open file success. + * Open image file, and map file to continuous memory if open file success. * or read image file from array. Default load from IMG file */ if(rst_opt == OPT_SYSTEM_RESET) { diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index c4586b0..dd1954d 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -40,7 +40,7 @@ static u32 RF_CHANNEL_TABLE_ZEBRA[] = { * and do register read/write * input: u32 dwBitMask //taget bit pos in the addr to be modified * output: none - * return: u32 return the shift bit bit position of the mask + * return: u32 return the shift bit position of the mask * ****************************************************************************/ u32 rtl8192_CalculateBitShift(u32 dwBitMask) { @@ -176,7 +176,7 @@ u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - // TODO: we should not delay such a long time. Ask help from SD3 + // TODO: we should not delay such a long time. Ask for help from SD3 msleep(1); ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); @@ -252,7 +252,7 @@ void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath NewOffset = Offset; } - // Put write addr in [5:0] and write data in [31:16] + // Put write addr in [5:0] and write data in [31:16] DataAndAddr = (Data<<16) | (NewOffset&0x3f); // Write Operation @@ -525,7 +525,7 @@ void rtl8192_phy_configmac(struct net_device* dev) } /****************************************************************************** - *function: This function do dirty work + *function: This function does dirty work * input: dev * output: none * return: none @@ -578,7 +578,7 @@ void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType) void rtl8192_InitBBRFRegDef(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); -// RF Interface Sowrtware Control +// RF Interface Software Control priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874 @@ -602,7 +602,7 @@ void rtl8192_InitBBRFRegDef(struct net_device* dev) priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) - //Addr of LSSI. Wirte RF register by driver + //Addr of LSSI. Write RF register by driver priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; @@ -1384,7 +1384,7 @@ u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u } /****************************************************************************** - *function: This function does acturally set channel work + *function: This function does actually set channel work * input: struct net_device *dev * u8 channel * output: none @@ -1425,7 +1425,7 @@ void rtl8192_SwChnl_WorkItem(struct net_device *dev) } /****************************************************************************** - *function: This function scheduled actural workitem to set channel + *function: This function scheduled actual work item to set channel * input: net_device dev * u8 channel //channel to set * output: none diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h index 06b0b53..50f24dc 100644 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ b/drivers/staging/rtl8192u/r819xU_phyreg.h @@ -443,7 +443,7 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRFExtend 0x20000000 //CCK Rx inital gain polarity #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 #define bCCKRxRFSettle 0x1f //AGCsamp_dly diff --git a/drivers/staging/rtl8712/big_endian.h b/drivers/staging/rtl8712/big_endian.h deleted file mode 100644 index b16f8ec..0000000 --- a/drivers/staging/rtl8712/big_endian.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE <wlanfae@realtek.com> - * Larry Finger <Larry.Finger@lwfinger.net> - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H -#define _LINUX_BYTEORDER_BIG_ENDIAN_H - -#ifndef __BIG_ENDIAN -#define __BIG_ENDIAN 4321 -#endif -#ifndef __BIG_ENDIAN_BITFIELD -#define __BIG_ENDIAN_BITFIELD -#endif - -#include "swab.h" - -#define __constant_htonl(x) ((__u32)(x)) -#define __constant_ntohl(x) ((__u32)(x)) -#define __constant_htons(x) ((__u16)(x)) -#define __constant_ntohs(x) ((__u16)(x)) -#define __constant_cpu_to_le64(x) ___constant_swab64((x)) -#define __constant_le64_to_cpu(x) ___constant_swab64((x)) -#define __constant_cpu_to_le32(x) ___constant_swab32((x)) -#define __constant_le32_to_cpu(x) ___constant_swab32((x)) -#define __constant_cpu_to_le16(x) ___constant_swab16((x)) -#define __constant_le16_to_cpu(x) ___constant_swab16((x)) -#define __constant_cpu_to_be64(x) ((__u64)(x)) -#define __constant_be64_to_cpu(x) ((__u64)(x)) -#define __constant_cpu_to_be32(x) ((__u32)(x)) -#define __constant_be32_to_cpu(x) ((__u32)(x)) -#define __constant_cpu_to_be16(x) ((__u16)(x)) -#define __constant_be16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_le64(x) __swab64((x)) -#define __le64_to_cpu(x) __swab64((x)) -#define __cpu_to_le32(x) __swab32((x)) -#define __le32_to_cpu(x) __swab32((x)) -#define __cpu_to_le16(x) __swab16((x)) -#define __le16_to_cpu(x) __swab16((x)) -#define __cpu_to_be64(x) ((__u64)(x)) -#define __be64_to_cpu(x) ((__u64)(x)) -#define __cpu_to_be32(x) ((__u32)(x)) -#define __be32_to_cpu(x) ((__u32)(x)) -#define __cpu_to_be16(x) ((__u16)(x)) -#define __be16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_le64p(x) __swab64p((x)) -#define __le64_to_cpup(x) __swab64p((x)) -#define __cpu_to_le32p(x) __swab32p((x)) -#define __le32_to_cpup(x) __swab32p((x)) -#define __cpu_to_le16p(x) __swab16p((x)) -#define __le16_to_cpup(x) __swab16p((x)) -#define __cpu_to_be64p(x) (*(__u64 *)(x)) -#define __be64_to_cpup(x) (*(__u64 *)(x)) -#define __cpu_to_be32p(x) (*(__u32 *)(x)) -#define __be32_to_cpup(x) (*(__u32 *)(x)) -#define __cpu_to_be16p(x) (*(__u16 *)(x)) -#define __be16_to_cpup(x) (*(__u16 *)(x)) -#define __cpu_to_le64s(x) __swab64s((x)) -#define __le64_to_cpus(x) __swab64s((x)) -#define __cpu_to_le32s(x) __swab32s((x)) -#define __le32_to_cpus(x) __swab32s((x)) -#define __cpu_to_le16s(x) __swab16s((x)) -#define __le16_to_cpus(x) __swab16s((x)) -#define __cpu_to_be64s(x) do {} while (0) -#define __be64_to_cpus(x) do {} while (0) -#define __cpu_to_be32s(x) do {} while (0) -#define __be32_to_cpus(x) do {} while (0) -#define __cpu_to_be16s(x) do {} while (0) -#define __be16_to_cpus(x) do {} while (0) - -#include "generic.h" - -#endif /* _LINUX_BYTEORDER_BIG_ENDIAN_H */ - diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index e83665d..62b5566 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -146,7 +146,7 @@ struct dvobj_priv { /** * struct _adapter - the main adapter structure for this device. * - * bup: True indicates that the interface is Up. + * bup: True indicates that the interface is up. */ struct _adapter { struct dvobj_priv dvobjpriv; diff --git a/drivers/staging/rtl8712/generic.h b/drivers/staging/rtl8712/generic.h deleted file mode 100644 index 8868c9f..0000000 --- a/drivers/staging/rtl8712/generic.h +++ /dev/null @@ -1,178 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE <wlanfae@realtek.com> - * Larry Finger <Larry.Finger@lwfinger.net> - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_GENERIC_H -#define _LINUX_BYTEORDER_GENERIC_H - -/* - * linux/byteorder_generic.h - * Generic Byte-reordering support - * - * Francois-Rene Rideau <fare@tunes.org> 19970707 - * gathered all the good ideas from all asm-foo/byteorder.h into one file, - * cleaned them up. - * I hope it is compliant with non-GCC compilers. - * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, - * because I wasn't sure it would be ok to put it in types.h - * Upgraded it to 2.1.43 - * Francois-Rene Rideau <fare@tunes.org> 19971012 - * Upgraded it to 2.1.57 - * to please Linus T., replaced huge #ifdef's between little/big endian - * by nestedly #include'd files. - * Francois-Rene Rideau <fare@tunes.org> 19971205 - * Made it to 2.1.71; now a facelift: - * Put files under include/linux/byteorder/ - * Split swab from generic support. - * - * TODO: - * = Regular kernel maintainers could also replace all these manual - * byteswap macros that remain, disseminated among drivers, - * after some grep or the sources... - * = Linus might want to rename all these macros and files to fit his taste, - * to fit his personal naming scheme. - * = it seems that a few drivers would also appreciate - * nybble swapping support... - * = every architecture could add their byteswap macro in asm/byteorder.h - * see how some architectures already do (i386, alpha, ppc, etc) - * = cpu_to_beXX and beXX_to_cpu might some day need to be well - * distinguished throughout the kernel. This is not the case currently, - * since little endian, big endian, and pdp endian machines needn't it. - * But this might be the case for, say, a port of Linux to 20/21 bit - * architectures (and F21 Linux addict around?). - */ - -/* - * The following macros are to be defined by <asm/byteorder.h>: - * - * Conversion of long and short int between network and host format - * ntohl(__u32 x) - * ntohs(__u16 x) - * htonl(__u32 x) - * htons(__u16 x) - * It seems that some programs (which? where? or perhaps a standard? POSIX?) - * might like the above to be functions, not macros (why?). - * if that's true, then detect them, and take measures. - * Anyway, the measure is: define only ___ntohl as a macro instead, - * and in a separate file, have - * unsigned long inline ntohl(x){return ___ntohl(x);} - * - * The same for constant arguments - * __constant_ntohl(__u32 x) - * __constant_ntohs(__u16 x) - * __constant_htonl(__u32 x) - * __constant_htons(__u16 x) - * - * Conversion of XX-bit integers (16- 32- or 64-) - * between native CPU format and little/big endian format - * 64-bit stuff only defined for proper architectures - * cpu_to_[bl]eXX(__uXX x) - * [bl]eXX_to_cpu(__uXX x) - * - * The same, but takes a pointer to the value to convert - * cpu_to_[bl]eXXp(__uXX x) - * [bl]eXX_to_cpup(__uXX x) - * - * The same, but change in situ - * cpu_to_[bl]eXXs(__uXX x) - * [bl]eXX_to_cpus(__uXX x) - * - * See asm-foo/byteorder.h for examples of how to provide - * architecture-optimized versions - * - */ - - -/* - * inside the kernel, we can use nicknames; - * outside of it, we must avoid POSIX namespace pollution... - */ -#define cpu_to_le64 __cpu_to_le64 -#define le64_to_cpu __le64_to_cpu -#define cpu_to_le32 __cpu_to_le32 -#define le32_to_cpu __le32_to_cpu -#define cpu_to_le16 __cpu_to_le16 -#define le16_to_cpu __le16_to_cpu -#define cpu_to_be64 __cpu_to_be64 -#define be64_to_cpu __be64_to_cpu -#define cpu_to_be32 __cpu_to_be32 -#define be32_to_cpu __be32_to_cpu -#define cpu_to_be16 __cpu_to_be16 -#define be16_to_cpu __be16_to_cpu -#define cpu_to_le64p __cpu_to_le64p -#define le64_to_cpup __le64_to_cpup -#define cpu_to_le32p __cpu_to_le32p -#define le32_to_cpup __le32_to_cpup -#define cpu_to_le16p __cpu_to_le16p -#define le16_to_cpup __le16_to_cpup -#define cpu_to_be64p __cpu_to_be64p -#define be64_to_cpup __be64_to_cpup -#define cpu_to_be32p __cpu_to_be32p -#define be32_to_cpup __be32_to_cpup -#define cpu_to_be16p __cpu_to_be16p -#define be16_to_cpup __be16_to_cpup -#define cpu_to_le64s __cpu_to_le64s -#define le64_to_cpus __le64_to_cpus -#define cpu_to_le32s __cpu_to_le32s -#define le32_to_cpus __le32_to_cpus -#define cpu_to_le16s __cpu_to_le16s -#define le16_to_cpus __le16_to_cpus -#define cpu_to_be64s __cpu_to_be64s -#define be64_to_cpus __be64_to_cpus -#define cpu_to_be32s __cpu_to_be32s -#define be32_to_cpus __be32_to_cpus -#define cpu_to_be16s __cpu_to_be16s -#define be16_to_cpus __be16_to_cpus - - -/* - * Handle ntohl and suches. These have various compatibility - * issues - like we want to give the prototype even though we - * also have a macro for them in case some strange program - * wants to take the address of the thing or something.. - * - * Note that these used to return a "long" in libc5, even though - * long is often 64-bit these days.. Thus the casts. - * - * They have to be macros in order to do the constant folding - * correctly - if the argument passed into a inline function - * it is no longer constant according to gcc.. - */ - -#undef ntohl -#undef ntohs -#undef htonl -#undef htons - -/* - * Do the prototypes. Somebody might want to take the - * address or some such sick thing.. - */ -extern __u32 ntohl(__u32); -extern __u32 htonl(__u32); -extern unsigned short int ntohs(unsigned short int); -extern unsigned short int htons(unsigned short int); - -#endif /* _LINUX_BYTEORDER_GENERIC_H */ - diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index cc893c0..cb9d4cf 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -36,7 +36,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "usb_osintf.h" #define FWBUFF_ALIGN_SZ 512 diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h index 3c0092b..21515c3 100644 --- a/drivers/staging/rtl8712/ieee80211.h +++ b/drivers/staging/rtl8712/ieee80211.h @@ -705,7 +705,7 @@ enum ieee80211_state { IEEE80211_ASSOCIATING_RETRY, /* the association procedure is sending AUTH request*/ IEEE80211_ASSOCIATING_AUTHENTICATING, - /* the association procedure has successfully authentcated + /* the association procedure has successfully authenticated * and is sending association request */ IEEE80211_ASSOCIATING_AUTHENTICATED, diff --git a/drivers/staging/rtl8712/if_ether.h b/drivers/staging/rtl8712/if_ether.h deleted file mode 100644 index 2bbe527..0000000 --- a/drivers/staging/rtl8712/if_ether.h +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE <wlanfae@realtek.com> - * Larry Finger <Larry.Finger@lwfinger.net> - * - ******************************************************************************/ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Global definitions for the Ethernet IEEE 802.3 interface. - * - * Version: @(#)if_ether.h 1.0.1a 02/08/94 - * - * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * Donald Becker, <becker@super.org> - * Alan Cox, <alan@redhat.com> - * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _LINUX_IF_ETHER_H -#define _LINUX_IF_ETHER_H - -/* - * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble - * and FCS/CRC (frame check sequence). - */ - -#define ETH_ALEN 6 /* Octets in one ethernet addr */ -#define ETH_HLEN 14 /* Total octets in header. */ -#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ -#define ETH_DATA_LEN 1500 /* Max. octets in payload */ -#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ - -/* - * These are the defined Ethernet Protocol ID's. - */ - -#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ -#define ETH_P_PUP 0x0200 /* Xerox PUP packet */ -#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_X25 0x0805 /* CCITT X.25 */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ -#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet - * [ NOT AN OFFICIAL ID ] */ -#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ -#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr - * Trans packet */ -#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ -#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ -#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ -#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ -#define ETH_P_LAT 0x6004 /* DEC LAT */ -#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ -#define ETH_P_CUST 0x6006 /* DEC Customer use */ -#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ -#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ -#define ETH_P_ATALK 0x809B /* Appletalk DDP */ -#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ -#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ -#define ETH_P_IPX 0x8137 /* IPX over DIX */ -#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ -#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ -#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ -#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ -#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport - * over Ethernet - */ - -/* - * Non DIX types. Won't clash for 1500 types. - */ - -#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ -#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ -#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ -#define ETH_P_802_2 0x0004 /* 802.2 frames */ -#define ETH_P_SNAP 0x0005 /* Internal only */ -#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ -#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ -#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ -#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ -#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ -#define ETH_P_TR_802_2 0x0011i /* 802.2 frames */ -#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ -#define ETH_P_CONTROL 0x0016 /* Card specific control frames */ -#define ETH_P_IRDA 0x0017 /* Linux-IrDA */ -#define ETH_P_ECONET 0x0018 /* Acorn Econet */ - -/* - * This is an Ethernet frame header. - */ - -struct ethhdr { - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -struct _vlan { - unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID*/ - unsigned short h_vlan_encapsulated_proto; -}; - - - -#define get_vlan_id(pvlan) ((ntohs((unsigned short)pvlan->h_vlan_TCI)) & 0xfff) -#define get_vlan_priority(pvlan) ((ntohs((unsigned short)\ - pvlan->h_vlan_TCI)) >> 13) -#define get_vlan_encap_proto(pvlan) (ntohs((unsigned short)\ - pvlan->h_vlan_encapsulated_proto)) - - -#endif /* _LINUX_IF_ETHER_H */ - diff --git a/drivers/staging/rtl8712/ip.h b/drivers/staging/rtl8712/ip.h deleted file mode 100644 index f37b0f8..0000000 --- a/drivers/staging/rtl8712/ip.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Definitions for the IP protocol. - * - * Version: @(#)ip.h 1.0.2 04/28/93 - * - * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#ifndef _LINUX_IP_H -#define _LINUX_IP_H - -#include "rtl871x_byteorder.h" - -/* SOL_IP socket options */ - -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_MINCOST 0x02 - -#define IPTOS_PREC_MASK 0xE0 -#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - -/* IP options */ -#define IPOPT_COPY 0x80 -#define IPOPT_CLASS_MASK 0x60 -#define IPOPT_NUMBER_MASK 0x1f - -#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) -#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) -#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_MEASUREMENT 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_END (0 | IPOPT_CONTROL) -#define IPOPT_NOOP (1 | IPOPT_CONTROL) -#define IPOPT_SEC (2 | IPOPT_CONTROL|IPOPT_COPY) -#define IPOPT_LSRR (3 | IPOPT_CONTROL|IPOPT_COPY) -#define IPOPT_TIMESTAMP (4 | IPOPT_MEASUREMENT) -#define IPOPT_RR (7 | IPOPT_CONTROL) -#define IPOPT_SID (8 | IPOPT_CONTROL | IPOPT_COPY) -#define IPOPT_SSRR (9 | IPOPT_CONTROL | IPOPT_COPY) -#define IPOPT_RA (20 | IPOPT_CONTROL | IPOPT_COPY) - -#define IPVERSION 4 -#define MAXTTL 255 -#define IPDEFTTL 64 - -/* struct timestamp, struct route and MAX_ROUTES are removed. - * - * REASONS: it is clear that nobody used them because: - * - MAX_ROUTES value was wrong. - * - "struct route" was wrong. - * - "struct timestamp" had fatally misaligned bitfields and was completely - * unusable. - */ - -#define IPOPT_OPTVAL 0 -#define IPOPT_OLEN 1 -#define IPOPT_OFFSET 2 -#define IPOPT_MINOFF 4 -#define MAX_IPOPTLEN 40 -#define IPOPT_NOP IPOPT_NOOP -#define IPOPT_EOL IPOPT_END -#define IPOPT_TS IPOPT_TIMESTAMP - -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -struct ip_options { - __u32 faddr; /* Saved first hop address */ - unsigned char optlen; - unsigned char srr; - unsigned char rr; - unsigned char ts; - unsigned char is_setbyuser:1, /* Set by setsockopt? */ - is_data:1, /* Options in __data, rather than skb */ - is_strictroute:1, /* Strict source route */ - srr_is_hit:1, /* Packet destination addr was our one*/ - is_changed:1, /* IP checksum more not valid */ - rr_needaddr:1, /* Need to record addr of outgoing dev*/ - ts_needtime:1, /* Need to record timestamp */ - ts_needaddr:1; /* Need to record addr of outgoing dev*/ - unsigned char router_alert; - unsigned char __pad1; - unsigned char __pad2; - unsigned char __data[0]; -}; - -#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) - -struct iphdr { -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 ihl:4, - version:4; -#elif defined(__BIG_ENDIAN_BITFIELD) - __u8 version:4, - ihl:4; -#else -#error "Please fix <asm/byteorder.h>" -#endif - __u8 tos; - __u16 tot_len; - __u16 id; - __u16 frag_off; - __u8 ttl; - __u8 protocol; - __u16 check; - __u32 saddr; - __u32 daddr; - /*The options start here. */ -}; - -#endif /* _LINUX_IP_H */ - diff --git a/drivers/staging/rtl8712/little_endian.h b/drivers/staging/rtl8712/little_endian.h deleted file mode 100644 index cd57d6c..0000000 --- a/drivers/staging/rtl8712/little_endian.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE <wlanfae@realtek.com> - * Larry Finger <Larry.Finger@lwfinger.net> - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H -#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H - -#ifndef __LITTLE_ENDIAN -#define __LITTLE_ENDIAN 1234 -#endif -#ifndef __LITTLE_ENDIAN_BITFIELD -#define __LITTLE_ENDIAN_BITFIELD -#endif - -#include "swab.h" - -#define __constant_htonl(x) ___constant_swab32((x)) -#define __constant_ntohl(x) ___constant_swab32((x)) -#define __constant_htons(x) ___constant_swab16((x)) -#define __constant_ntohs(x) ___constant_swab16((x)) -#define __constant_cpu_to_le64(x) ((__u64)(x)) -#define __constant_le64_to_cpu(x) ((__u64)(x)) -#define __constant_cpu_to_le32(x) ((__u32)(x)) -#define __constant_le32_to_cpu(x) ((__u32)(x)) -#define __constant_cpu_to_le16(x) ((__u16)(x)) -#define __constant_le16_to_cpu(x) ((__u16)(x)) -#define __constant_cpu_to_be64(x) ___constant_swab64((x)) -#define __constant_be64_to_cpu(x) ___constant_swab64((x)) -#define __constant_cpu_to_be32(x) ___constant_swab32((x)) -#define __constant_be32_to_cpu(x) ___constant_swab32((x)) -#define __constant_cpu_to_be16(x) ___constant_swab16((x)) -#define __constant_be16_to_cpu(x) ___constant_swab16((x)) -#define __cpu_to_le64(x) ((__u64)(x)) -#define __le64_to_cpu(x) ((__u64)(x)) -#define __cpu_to_le32(x) ((__u32)(x)) -#define __le32_to_cpu(x) ((__u32)(x)) -#define __cpu_to_le16(x) ((__u16)(x)) -#define __le16_to_cpu(x) ((__u16)(x)) -#define __cpu_to_be64(x) __swab64((x)) -#define __be64_to_cpu(x) __swab64((x)) -#define __cpu_to_be32(x) __swab32((x)) -#define __be32_to_cpu(x) __swab32((x)) -#define __cpu_to_be16(x) __swab16((x)) -#define __be16_to_cpu(x) __swab16((x)) -#define __cpu_to_le64p(x) (*(__u64 *)(x)) -#define __le64_to_cpup(x) (*(__u64 *)(x)) -#define __cpu_to_le32p(x) (*(__u32 *)(x)) -#define __le32_to_cpup(x) (*(__u32 *)(x)) -#define __cpu_to_le16p(x) (*(__u16 *)(x)) -#define __le16_to_cpup(x) (*(__u16 *)(x)) -#define __cpu_to_be64p(x) __swab64p((x)) -#define __be64_to_cpup(x) __swab64p((x)) -#define __cpu_to_be32p(x) __swab32p((x)) -#define __be32_to_cpup(x) __swab32p((x)) -#define __cpu_to_be16p(x) __swab16p((x)) -#define __be16_to_cpup(x) __swab16p((x)) -#define __cpu_to_le64s(x) do {} while (0) -#define __le64_to_cpus(x) do {} while (0) -#define __cpu_to_le32s(x) do {} while (0) -#define __le32_to_cpus(x) do {} while (0) -#define __cpu_to_le16s(x) do {} while (0) -#define __le16_to_cpus(x) do {} while (0) -#define __cpu_to_be64s(x) __swab64s((x)) -#define __be64_to_cpus(x) __swab64s((x)) -#define __cpu_to_be32s(x) __swab32s((x)) -#define __be32_to_cpus(x) __swab32s((x)) -#define __cpu_to_be16s(x) __swab16s((x)) -#define __be16_to_cpus(x) __swab16s((x)) - -#include "generic.h" - -#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ - diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 7bbd53a..448f00d 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -52,7 +52,7 @@ static int lbkmode = RTL8712_AIR_TRX; static int hci = RTL8712_USB; static int ampdu_enable = 1;/*for enable tx_ampdu*/ -/* The video_mode variable is for vedio mode.*/ +/* The video_mode variable is for video mode.*/ /* It may be specify when inserting module with video_mode=1 parameter.*/ static int video_mode = 1; /* enable video mode*/ @@ -248,7 +248,7 @@ static u32 start_drv_threads(struct _adapter *padapter) void r8712_stop_drv_threads(struct _adapter *padapter) { - /*Below is to termindate r8712_cmd_thread & event_thread...*/ + /*Below is to terminate r8712_cmd_thread & event_thread...*/ up(&padapter->cmdpriv.cmd_queue_sema); if (padapter->cmdThread) _down_sema(&padapter->cmdpriv.terminate_cmdthread_sema); diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index 9ba6033..f1ccc7e 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -29,7 +29,6 @@ #define _SUCCESS 1 #define _FAIL 0 -#include <linux/version.h> #include <linux/spinlock.h> #include <linux/interrupt.h> @@ -107,8 +106,6 @@ static inline void _set_workitem(_workitem *pwork) schedule_work(pwork); } -#include "rtl871x_byteorder.h" - #ifndef BIT #define BIT(x) (1 << (x)) #endif diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 9f6ebc4..088647c 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -50,7 +50,6 @@ #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "rtl871x_byteorder.h" #include "rtl871x_ioctl_set.h" static void check_hw_pbc(struct _adapter *padapter) @@ -69,7 +68,7 @@ static void check_hw_pbc(struct _adapter *padapter) * After trigger PBC, the variable will be set to false */ DBG_8712("CheckPbcGPIO - PBC is pressed !!!!\n"); /* 0 is the default value and it means the application monitors - * the HW PBC doesn't privde its pid to driver. */ + * the HW PBC doesn't provide its pid to driver. */ if (padapter->pid == 0) return; kill_pid(find_vpid(padapter->pid), SIGUSR1, 1); @@ -382,7 +381,7 @@ _next: *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) | (pcmd->cmdcode << 16) | (pcmdpriv->cmd_seq << 24)); - pcmdbuf += 2 ; /* 8 bytes aligment */ + pcmdbuf += 2 ; /* 8 bytes alignment */ memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); while (check_cmd_fifo(padapter, wr_sz) == _FAIL) { if ((padapter->bDriverStopped == true) || @@ -471,7 +470,7 @@ void r8712_event_handle(struct _adapter *padapter, uint *peventbuf) pevt_priv->event_seq++; /* update evt_seq */ if (pevt_priv->event_seq > 127) pevt_priv->event_seq = 0; - peventbuf = peventbuf + 2; /* move to event content, 8 bytes aligment */ + peventbuf = peventbuf + 2; /* move to event content, 8 bytes alignment */ if (peventbuf) { event_callback = wlanevents[evt_code].event_callback; if (event_callback) diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h index 766a646..039ab3e 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.h +++ b/drivers/staging/rtl8712/rtl8712_cmd.h @@ -121,7 +121,7 @@ enum rtl8712_h2c_cmd { GEN_CMD_CODE(_GetCurDataRate) , GEN_CMD_CODE(_GetTxRetrycnt), /* to record times that Tx retry to - * transmmit packet after association + * transmit packet after association */ GEN_CMD_CODE(_GetRxRetrycnt), /* to record total number of the * received frame with ReTry bit set in diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index b08e9a2..377fca9 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -417,7 +417,7 @@ u8 r8712_efuse_pg_packet_write(struct _adapter *padapter, const u8 offset, } else { /* write header fail */ bResult = false; if (0xFF == efuse_data) - return bResult; /* not thing damaged. */ + return bResult; /* nothing damaged. */ /* call rescue procedure */ if (fix_header(padapter, efuse_data, efuse_addr) == false) diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h index 884a821..138ea45 100644 --- a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h @@ -70,7 +70,7 @@ #define GPIOSEL_BT 2 /* BT_coex*/ #define GPIOSEL_WLANDBG 3 /* WLANDBG*/ #define GPIOSEL_GPIO_MASK (~(BIT(0)|BIT(1))) -/* HW Readio OFF switch (GPIO BIT) */ +/* HW Radio OFF switch (GPIO BIT) */ #define HAL_8192S_HW_GPIO_OFF_BIT BIT(3) #define HAL_8192S_HW_GPIO_OFF_MASK 0xF7 #define HAL_8192S_HW_GPIO_WPS_BIT BIT(4) diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h index d19865a..4c51fa3 100644 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ b/drivers/staging/rtl8712/rtl8712_hal.h @@ -83,7 +83,7 @@ struct fw_priv { /*8-bytes alignment required*/ unsigned char rfintfs; /* 0:SWSI, 1:HWSI, 2:HWPI*/ unsigned char def_nettype; unsigned char turboMode; - unsigned char lowPowerMode;/* 0: noral mode, 1: low power mode*/ + unsigned char lowPowerMode;/* 0: normal mode, 1: low power mode*/ /*--- long word 2 ----*/ unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/ unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */ @@ -123,7 +123,7 @@ struct fw_priv { /*8-bytes alignment required*/ unsigned char rsvd053; }; -struct fw_hdr {/*8-byte alinment required*/ +struct fw_hdr {/*8-byte alignment required*/ unsigned short signature; unsigned short version; /*0x8000 ~ 0x8FFF for FPGA version, *0x0000 ~ 0x7FFF for ASIC version,*/ diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index bac56e5..c9eb4b7 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -60,7 +60,7 @@ enum _LED_STATE_871x { * the # of times to blink is depend on time * for scanning. */ LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */ - LED_BLINK_StartToBlink = 8,/* Customzied for Sercomm Printer + LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer * Server case */ LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */ LED_TXRX_BLINK = 10, @@ -826,7 +826,7 @@ static void BlinkTimerCallback(unsigned long data) { struct LED_871x *pLed = (struct LED_871x *)data; - /* This fixed the crash problem on Fedora 12 when trying to do thei + /* This fixed the crash problem on Fedora 12 when trying to do the * insmod;ifconfig up;rmmod commands. */ if ((pLed->padapter->bSurpriseRemoved == true) || (pLed->padapter->bDriverStopped == true)) @@ -836,7 +836,7 @@ static void BlinkTimerCallback(unsigned long data) /* Description: * Callback function of LED BlinkWorkItem. - * We dispatch acture LED blink action according to LedStrategy. + * We dispatch actual LED blink action according to LedStrategy. */ static void BlinkWorkItemCallback(struct work_struct *work) { diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index fa6dc9c..8e82ce2 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -28,12 +28,13 @@ #define _RTL8712_RECV_C_ +#include <linux/if_ether.h> +#include <linux/ip.h> + #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "ip.h" -#include "if_ether.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" @@ -459,7 +460,7 @@ void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf) cmd_seq = (u8)((le32_to_cpu(voffset) >> 24) & 0x7f); eid = (u8)((le32_to_cpu(voffset) >> 16) & 0xff); r8712_event_handle(padapter, (uint *)poffset); - poffset += (cmd_len + 8);/*8 bytes aligment*/ + poffset += (cmd_len + 8);/*8 bytes alignment*/ } while (le32_to_cpu(voffset) & BIT(31)); } @@ -603,7 +604,7 @@ static int recv_indicatepkt_reorder(struct _adapter *padapter, } } spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); - /*s2. check if winstart_b(indicate_seq) needs to been updated*/ + /*s2. check if winstart_b(indicate_seq) needs to be updated*/ if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) goto _err_exit; /*s3. Insert all packet into Reorder Queue to maintain its ordering.*/ diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 6933319..3d23514 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -30,7 +30,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "osdep_intf.h" #include "usb_ops.h" diff --git a/drivers/staging/rtl8712/rtl871x_byteorder.h b/drivers/staging/rtl8712/rtl871x_byteorder.h deleted file mode 100644 index bd3703b..0000000 --- a/drivers/staging/rtl8712/rtl871x_byteorder.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * - ******************************************************************************/ -#ifndef _RTL871X_BYTEORDER_H_ -#define _RTL871X_BYTEORDER_H_ - -#if defined(__LITTLE_ENDIAN) -# include "little_endian.h" -#elif defined(__BIG_ENDIAN) -# include "big_endian.h" -#else -# error "Must be LITTLE/BIG Endian Host" -#endif - -#endif /* _RTL871X_BYTEORDER_H_ */ - diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index d77388b..659683e 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -50,7 +50,6 @@ #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "rtl871x_byteorder.h" /* Caller and the r8712_cmd_thread can protect cmd_q by spin_lock. diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h index 757ebf7..9d93189 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.h +++ b/drivers/staging/rtl8712/rtl871x_cmd.h @@ -720,7 +720,7 @@ struct DisconnectCtrlEx_param { * Result: * 0x00: success * 0x01: success, and check Response. - * 0x02: cmd ignored due to duplicated sequcne number + * 0x02: cmd ignored due to duplicated sequence number * 0x03: cmd dropped due to invalid cmd code * 0x04: reserved. */ diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h index d3d8727..dc23395 100644 --- a/drivers/staging/rtl8712/rtl871x_io.h +++ b/drivers/staging/rtl8712/rtl871x_io.h @@ -117,7 +117,7 @@ struct io_req { u32 command; u32 status; u8 *pbuf; - void (*_async_io_callback)(struct _adapter *padater, + void (*_async_io_callback)(struct _adapter *padapter, struct io_req *pio_req, u8 *cnxt); u8 *cnxt; }; diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index ef35bc29..35e781f 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -43,7 +43,6 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/version.h> #include <linux/io.h> #include <linux/semaphore.h> #include <net/iw_handler.h> @@ -242,7 +241,7 @@ static inline char *translate_scan(struct _adapter *padapter, /* Add frequency/channel */ iwe.cmd = SIOCGIWFREQ; { - /* check legel index */ + /* check legal index */ u8 dsconfig = pnetwork->network.Configuration.DSConfig; if (dsconfig >= 1 && dsconfig <= sizeof( ieee80211_wlan_frequencies) / sizeof(long)) @@ -810,11 +809,11 @@ static int r871x_wx_set_pmkid(struct net_device *dev, /* There are the BSSID information in the bssid.sa_data array. - If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear - all the PMKID information. If cmd is IW_PMKSA_ADD, it means the - wpa_supplicant wants to add a PMKID/BSSID to driver. + If cmd is IW_PMKSA_FLUSH, it means the wpa_supplicant wants to clear + all the PMKID information. If cmd is IW_PMKSA_ADD, it means the + wpa_supplicant wants to add a PMKID/BSSID to driver. If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to - remove a PMKID/BSSID from driver. + remove a PMKID/BSSID from driver. */ if (pPMK == NULL) return -EINVAL; @@ -924,7 +923,7 @@ static int r8711_wx_get_range(struct net_device *dev, range->max_qual.noise = 100; range->max_qual.updated = 7; /* Updated all three */ range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ + /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ range->avg_qual.level = 20 + -98; range->avg_qual.noise = 0; range->avg_qual.updated = 7; /* Updated all three */ @@ -1071,7 +1070,7 @@ FREE_EXT: * MAC# of a preferred Access Point. * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. * - * For this operation to succeed, there is no need for the interface to be Up. + * For this operation to succeed, there is no need for the interface to be up. * */ static int r8711_wx_set_wap(struct net_device *dev, @@ -2389,10 +2388,10 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev) struct iw_handler_def r871x_handlers_def = { .standard = r8711_handlers, - .num_standard = sizeof(r8711_handlers) / sizeof(iw_handler), + .num_standard = ARRAY_SIZE(r8711_handlers), .private = r8711_private_handler, .private_args = (struct iw_priv_args *)r8711_private_args, - .num_private = sizeof(r8711_private_handler) / sizeof(iw_handler), + .num_private = ARRAY_SIZE(r8711_private_handler), .num_private_args = sizeof(r8711_private_args) / sizeof(struct iw_priv_args), .get_wireless_stats = r871x_get_wireless_stats diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index fb29b42..f352b32 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -264,7 +264,7 @@ void r8712_set_802_11_infrastructure_mode(struct _adapter *padapter, (*pold_state == Ndis802_11Infrastructure) || (*pold_state == Ndis802_11IBSS)) { /* will clr Linked_state before this function, - * we must have chked whether issue dis-assoc_cmd or + * we must have checked whether issue dis-assoc_cmd or * not */ r8712_ind_disconnect(padapter); } diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 4277d03..dc7adc1 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -137,7 +137,7 @@ static void _free_network_nolock(struct mlme_priv *pmlmepriv, /* return the wlan_network with the matching addr - Shall be calle under atomic context... + Shall be called under atomic context... to avoid possible racing condition... */ static struct wlan_network *_r8712_find_network(struct __queue *scanned_queue, @@ -255,7 +255,7 @@ void r8712_free_network_queue(struct _adapter *dev) /* return the wlan_network with the matching addr - Shall be calle under atomic context... + Shall be called under atomic context... to avoid possible racing condition... */ static struct wlan_network *r8712_find_network(struct __queue *scanned_queue, @@ -1037,7 +1037,7 @@ void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf) * and the WiFi client will drop the data with seq number 0. * So, the 8712 firmware has to inform driver with receiving the * ADDBA-Req frame so that the driver can reset the - * sequence value of Rx reorder contorl. + * sequence value of Rx reorder control. */ void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf) { @@ -1775,7 +1775,7 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len) phtpriv->rx_ampdu_maxlen = max_ampdu_sz; } /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info - * if A-MPDU Rx is enabled, reseting rx_ordering_ctrl + * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl * wstart_b(indicate_seq) to default value=0xffff * todo: check if AP can send A-MPDU packets */ diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h index 71ca013..42bd0bf 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ b/drivers/staging/rtl8712/rtl871x_mlme.h @@ -69,8 +69,8 @@ since mlme_priv is a shared resource between many threads, like ISR/Call-Back functions, the OID handlers, and even timer functions. Each _queue has its own locks, already. Other items are protected by mlme_priv.lock. -To avoid possible dead lock, any thread trying to modifiying mlme_priv -SHALL not lock up more than one locks at a time! +To avoid possible dead lock, any thread trying to modify mlme_priv +SHALL not lock up more than one lock at a time! */ #define traffic_threshold 10 @@ -132,7 +132,7 @@ static inline sint get_fwstate(struct mlme_priv *pmlmepriv) * therefore set it to be the critical section... * * ### NOTE:#### (!!!!) - * TAKE CARE THAT BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock + * TAKE CARE BEFORE CALLING THIS FUNC, LOCK pmlmepriv->lock */ static inline void set_fwstate(struct mlme_priv *pmlmepriv, sint state) { diff --git a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h index 23532a7..8e25862 100644 --- a/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h +++ b/drivers/staging/rtl8712/rtl871x_mp_phy_regdef.h @@ -184,7 +184,7 @@ /*RxIQ DC offset, Rx digital filter, DC notch filter */ #define rOFDM0_XARxAFE 0xc10 -#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ +#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imbalance matrix */ #define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c #define rOFDM0_XCRxAFE 0xc20 @@ -603,7 +603,7 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 /* CCK Rx Iinital gain polarity */ +#define bCCKRFExtend 0x20000000 /* CCK Rx inital gain polarity */ #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 #define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 5b03b40..c9d1743 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -28,15 +28,15 @@ #define _RTL871X_RECV_C_ +#include <linux/ip.h> #include <linux/slab.h> +#include <linux/if_ether.h> #include <linux/kmemleak.h> #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" #include "mlme_osdep.h" -#include "ip.h" -#include "if_ether.h" #include "ethernet.h" #include "usb_ops.h" #include "wifi.h" diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index aa57e77..78f570b 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -30,7 +30,6 @@ #include "osdep_service.h" #include "drv_types.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "osdep_intf.h" #include "usb_ops.h" @@ -72,7 +71,7 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); spin_lock_init(&pxmitpriv->lock); /* - Please insert all the queue initializaiton using _init_queue below + Please insert all the queue initialization using _init_queue below */ pxmitpriv->adapter = padapter; _init_queue(&pxmitpriv->be_pending); diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h index 638b79b..ee90698 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.h +++ b/drivers/staging/rtl8712/rtl871x_xmit.h @@ -119,7 +119,7 @@ struct pkt_attrib { u8 priority; u8 encrypt; /* when 0 indicate no encrypt. when non-zero, - * indicate the encrypt algorith*/ + * indicate the encrypt algorithm*/ u8 iv_len; u8 icv_len; unsigned char iv[8]; diff --git a/drivers/staging/rtl8712/swab.h b/drivers/staging/rtl8712/swab.h deleted file mode 100644 index f127818..0000000 --- a/drivers/staging/rtl8712/swab.h +++ /dev/null @@ -1,131 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * Modifications for inclusion into the Linux staging tree are - * Copyright(c) 2010 Larry Finger. All rights reserved. - * - * Contact information: - * WLAN FAE <wlanfae@realtek.com> - * Larry Finger <Larry.Finger@lwfinger.net> - * - ******************************************************************************/ -#ifndef _LINUX_BYTEORDER_SWAB_H -#define _LINUX_BYTEORDER_SWAB_H - -#ifndef __u16 - #define __u16 unsigned short -#endif - -#ifndef __u32 - #define __u32 unsigned int -#endif - -#ifndef __u8 - #define __u8 unsigned char -#endif - -#ifndef __u64 - #define __u64 unsigned long long -#endif - - -static inline __u16 ___swab16(__u16 x) -{ - __u16 __x = x; - return (__u16)( - (((__u16)(__x) & (__u16)0x00ffU) << 8) | - (((__u16)(__x) & (__u16)0xff00U) >> 8)); - -} - -static inline __u32 ___swab32(__u32 x) -{ - __u32 __x = (x); - return (__u32)( - (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | - (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | - (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | - (((__u32)(__x) & (__u32)0xff000000UL) >> 24)); -} - -static inline __u64 ___swab64(__u64 x) -{ - __u64 __x = (x); - - return (__u64)( \ - (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ - (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ - (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ - (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ - (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ - (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ - (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ - (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56)); -} - -#ifndef __arch__swab16 -static inline __u16 __arch__swab16(__u16 x) -{ - return ___swab16(x); -} - -#endif - -#ifndef __arch__swab32 -static inline __u32 __arch__swab32(__u32 x) -{ - __u32 __tmp = (x) ; - return ___swab32(__tmp); -} -#endif - -#ifndef __arch__swab64 - -static inline __u64 __arch__swab64(__u64 x) -{ - __u64 __tmp = (x) ; - return ___swab64(__tmp); -} - - -#endif - -#define __swab16(x) __fswab16(x) -#define __swab32(x) __fswab32(x) -#define __swab64(x) __fswab64(x) - -static inline const __u16 __fswab16(__u16 x) -{ - return __arch__swab16(x); -} -static inline const __u32 __fswab32(__u32 x) -{ - return __arch__swab32(x); -} - -#define swab16 __swab16 -#define swab32 __swab32 -#define swab64 __swab64 -#define swab16p __swab16p -#define swab32p __swab32p -#define swab64p __swab64p -#define swab16s __swab16s -#define swab32s __swab32s -#define swab64s __swab64s - -#endif /* _LINUX_BYTEORDER_SWAB_H */ - diff --git a/drivers/staging/rtl8712/usb_halinit.c b/drivers/staging/rtl8712/usb_halinit.c index 46287c1..b4ae11a 100644 --- a/drivers/staging/rtl8712/usb_halinit.c +++ b/drivers/staging/rtl8712/usb_halinit.c @@ -141,7 +141,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) /* Enable AFE PLL Macro Block */ val8 = r8712_read8(padapter, AFE_PLL_CTRL); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); - /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ + /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ @@ -234,7 +234,7 @@ u8 r8712_usb_hal_bus_init(struct _adapter *padapter) udelay(500); r8712_write8(padapter, AFE_PLL_CTRL, (val8 | 0x11)); udelay(500); - /* Attatch AFE PLL to MACTOP/BB/PCIe Digital */ + /* Attach AFE PLL to MACTOP/BB/PCIe Digital */ val8 = r8712_read8(padapter, SYS_ISO_CTRL); r8712_write8(padapter, SYS_ISO_CTRL, (val8 & 0xEE)); /* Switch to 40M clock */ diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index e419b4f..9bd18e2 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -621,30 +621,28 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf) struct usb_device *udev = interface_to_usbdev(pusb_intf); usb_set_intfdata(pusb_intf, NULL); - if (padapter) { - if (padapter->fw_found) - release_firmware(padapter->fw); - /* never exit with a firmware callback pending */ - wait_for_completion(&padapter->rtl8712_fw_ready); - if (drvpriv.drv_registered == true) - padapter->bSurpriseRemoved = true; - if (pnetdev != NULL) { - /* will call netdev_close() */ - unregister_netdev(pnetdev); - } - flush_scheduled_work(); - udelay(1); - /*Stop driver mlme relation timer */ - if (padapter->fw_found) - r8712_stop_drv_timers(padapter); - r871x_dev_unload(padapter); - r8712_free_drv_sw(padapter); + if (padapter->fw_found) + release_firmware(padapter->fw); + /* never exit with a firmware callback pending */ + wait_for_completion(&padapter->rtl8712_fw_ready); + if (drvpriv.drv_registered == true) + padapter->bSurpriseRemoved = true; + if (pnetdev != NULL) { + /* will call netdev_close() */ + unregister_netdev(pnetdev); } + flush_scheduled_work(); + udelay(1); + /*Stop driver mlme relation timer */ + if (padapter->fw_found) + r8712_stop_drv_timers(padapter); + r871x_dev_unload(padapter); + r8712_free_drv_sw(padapter); usb_set_intfdata(pusb_intf, NULL); /* decrease the reference count of the usb device structure * when disconnect */ usb_put_dev(udev); - /* If we didn't unplug usb dongle and remove/insert modlue, driver + /* If we didn't unplug usb dongle and remove/insert module, driver * fails on sitesurvey for the first time when device is up. * Reset usb port for sitesurvey fail issue. */ if (udev->state != USB_STATE_NOTATTACHED) diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c index 5a8b0eb..c03508d 100644 --- a/drivers/staging/rtl8712/usb_ops.c +++ b/drivers/staging/rtl8712/usb_ops.c @@ -33,7 +33,6 @@ #include "osdep_intf.h" #include "usb_ops.h" #include "recv_osdep.h" -#include "rtl871x_byteorder.h" static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr) { diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index 277398c..793443e 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -26,7 +26,6 @@ #ifndef _WIFI_H_ #define _WIFI_H_ -#include "rtl871x_byteorder.h" #include <linux/compiler.h> #ifdef BIT diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index c970362..65542cb 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -29,14 +29,12 @@ #define _XMIT_OSDEP_C_ #include <linux/usb.h> +#include <linux/ip.h> +#include <linux/if_ether.h> #include "osdep_service.h" #include "drv_types.h" - -#include "if_ether.h" -#include "ip.h" -#include "rtl871x_byteorder.h" #include "wifi.h" #include "mlme_osdep.h" #include "xmit_osdep.h" diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c index b0e9071..6eef33b 100644 --- a/drivers/staging/rts5139/ms.c +++ b/drivers/staging/rts5139/ms.c @@ -2680,7 +2680,7 @@ static int mspro_set_rw_cmd(struct rts51x_chip *chip, u32 start_sec, return STATUS_SUCCESS; } -void mspro_stop_seq_mode(struct rts51x_chip *chip) +static void mspro_stop_seq_mode(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -3149,7 +3149,7 @@ Fail: TRACE_RET(chip, STATUS_FAIL); sec_cnt = chip->rsp_buf[0]; - RTS51X_DEBUGP("%d pages need be trasferred, %d pages remained\n", + RTS51X_DEBUGP("%d pages need be transferred, %d pages remained\n", (int)page_cnt, (int)sec_cnt); page_addr = start_page + (page_cnt - sec_cnt); @@ -3864,7 +3864,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, log_blk = (u16) (start_sector >> ms_card->block_shift); start_page = (u8) (start_sector & ms_card->page_off); - for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { if (log_blk < ms_start_idx[seg_no + 1]) break; } @@ -4020,7 +4020,8 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, log_blk++; - for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; + seg_no++) { if (log_blk < ms_start_idx[seg_no + 1]) break; } @@ -4134,7 +4135,7 @@ void ms_cleanup_work(struct rts51x_chip *chip) } } -int ms_power_off_card3v3(struct rts51x_chip *chip) +static int ms_power_off_card3v3(struct rts51x_chip *chip) { int retval; diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h index 3ce1dc9..0321d06 100644 --- a/drivers/staging/rts5139/ms.h +++ b/drivers/staging/rts5139/ms.h @@ -234,7 +234,6 @@ void mspro_polling_format_status(struct rts51x_chip *chip); void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); -void mspro_stop_seq_mode(struct rts51x_chip *chip); int reset_ms_card(struct rts51x_chip *chip); int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); @@ -242,7 +241,6 @@ int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, int short_data_len, int quick_format); void ms_free_l2p_tbl(struct rts51x_chip *chip); void ms_cleanup_work(struct rts51x_chip *chip); -int ms_power_off_card3v3(struct rts51x_chip *chip); int release_ms_card(struct rts51x_chip *chip); int ms_delay_write(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c index 154b523..057d96c 100644 --- a/drivers/staging/rts5139/ms_mg.c +++ b/drivers/staging/rts5139/ms_mg.c @@ -38,7 +38,7 @@ #ifdef SUPPORT_MAGIC_GATE -int mg_check_int_error(struct rts51x_chip *chip) +static int mg_check_int_error(struct rts51x_chip *chip) { u8 value; @@ -444,7 +444,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) * * Since the extra 4 bytes data is just only a prefix to original data * that read from medium, so that the 4-byte data pushed into Ring buffer - * precedes data tramsinssion from medium to Ring buffer by DMA mechanisim + * precedes data transmission from medium to Ring buffer by DMA mechanism * in order to get maximum performance and minimum code size simultaneously. */ int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index 2b9f785..c3fe7dd 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -56,12 +56,6 @@ MODULE_DESCRIPTION(RTS51X_DESC); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); -#ifdef SCSI_SCAN_DELAY -static unsigned int delay_use = 5; -module_param(delay_use, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); -#endif - static int auto_delink_en; module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); @@ -114,7 +108,7 @@ static inline void usb_autopm_disable(struct usb_interface *intf) usb_autopm_get_interface(intf); } -void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) { RTS51X_DEBUGP("Ready to enter SS state\n"); usb_autopm_enable(chip->usb->pusb_intf); @@ -207,7 +201,7 @@ int rts51x_reset_resume(struct usb_interface *iface) #else /* CONFIG_PM */ -void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +static void rts51x_try_to_enter_ss(struct rts51x_chip *chip) { } @@ -364,11 +358,6 @@ static int rts51x_polling_thread(void *__chip) { struct rts51x_chip *chip = (struct rts51x_chip *)__chip; -#ifdef SCSI_SCAN_DELAY - /* Wait until SCSI scan finished */ - wait_timeout((delay_use + 5) * HZ); -#endif - for (;;) { wait_timeout(POLLING_INTERVAL); @@ -432,38 +421,6 @@ static int rts51x_polling_thread(void *__chip) return 0; } -#ifdef SCSI_SCAN_DELAY -/* Thread to carry out delayed SCSI-device scanning */ -static int rts51x_scan_thread(void *__chip) -{ - struct rts51x_chip *chip = (struct rts51x_chip *)__chip; - - printk(KERN_DEBUG - "rts51x: device found at %d\n", chip->usb->pusb_dev->devnum); - - set_freezable(); - /* Wait for the timeout to expire or for a disconnect */ - if (delay_use > 0) { - printk(KERN_DEBUG "rts51x: waiting for device " - "to settle before scanning\n"); - wait_event_freezable_timeout(chip->usb->delay_wait, - test_bit(FLIDX_DONT_SCAN, - &chip->usb->dflags), - delay_use * HZ); - } - - /* If the device is still connected, perform the scanning */ - if (!test_bit(FLIDX_DONT_SCAN, &chip->usb->dflags)) { - scsi_scan_host(rts51x_to_host(chip)); - printk(KERN_DEBUG "rts51x: device scan complete\n"); - - /* Should we unbind if no devices were detected? */ - } - - complete_and_exit(&chip->usb->scanning_done, 0); -} -#endif - /* Associate our private data with the USB device */ static int associate_dev(struct rts51x_chip *chip, struct usb_interface *intf) { @@ -521,7 +478,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) { struct rts51x_option *option = &(chip->option); - option->led_blink_speed = 7; option->mspro_formatter_enable = 1; option->fpga_sd_sdr104_clk = CLK_100; @@ -549,7 +505,6 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->ss_en = ss_en; option->ss_delay = ss_delay; - option->needs_remote_wakeup = needs_remote_wakeup; option->auto_delink_en = auto_delink_en; @@ -561,10 +516,7 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->rts5129_D3318_off_enable = 0; option->sd20_pad_drive = 0; option->reset_or_rw_fail_set_pad_drive = 1; - option->rcc_fail_flag = 0; - option->rcc_bug_fix_en = 1; option->debounce_num = 2; - option->polling_time = 100; option->led_toggle_interval = 6; option->xd_rwn_step = 0; option->sd_send_status_en = 0; @@ -737,15 +689,6 @@ static void quiesce_and_remove_host(struct rts51x_chip *chip) if (rts51x->pusb_dev->state == USB_STATE_NOTATTACHED) set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); -#ifdef SCSI_SCAN_DELAY - /* Prevent SCSI-scanning (if it hasn't started yet) - * and wait for the SCSI-scanning thread to stop. - */ - set_bit(FLIDX_DONT_SCAN, &rts51x->dflags); - wake_up(&rts51x->delay_wait); - wait_for_completion(&rts51x->scanning_done); -#endif - /* Removing the host will perform an orderly shutdown: caches * synchronized, disks spun down, etc. */ @@ -757,9 +700,6 @@ static void quiesce_and_remove_host(struct rts51x_chip *chip) scsi_lock(host); set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); scsi_unlock(host); -#ifdef SCSI_SCAN_DELAY - wake_up(&rts51x->delay_wait); -#endif } /* Second stage of disconnect processing: deallocate all resources */ @@ -818,10 +758,6 @@ static int rts51x_probe(struct usb_interface *intf, init_completion(&rts51x->control_exit); init_completion(&rts51x->polling_exit); init_completion(&(rts51x->notify)); -#ifdef SCSI_SCAN_DELAY - init_waitqueue_head(&rts51x->delay_wait); - init_completion(&rts51x->scanning_done); -#endif chip->usb = rts51x; @@ -855,22 +791,7 @@ static int rts51x_probe(struct usb_interface *intf, printk(KERN_WARNING RTS51X_TIP "Unable to add the scsi host\n"); goto BadDevice; } -#ifdef SCSI_SCAN_DELAY - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_create(rts51x_scan_thread, chip, RTS51X_SCAN_THREAD); - if (IS_ERR(th)) { - printk(KERN_WARNING RTS51X_TIP - "Unable to start the device-scanning thread\n"); - complete(&rts51x->scanning_done); - quiesce_and_remove_host(chip); - result = PTR_ERR(th); - goto BadDevice; - } - - wake_up_process(th); -#else scsi_scan_host(rts51x_to_host(chip)); -#endif /* Start up our polling thread */ th = kthread_run(rts51x_polling_thread, chip, RTS51X_POLLING_THREAD); diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h index b2c5839..ecc0109 100644 --- a/drivers/staging/rts5139/rts51x.h +++ b/drivers/staging/rts5139/rts51x.h @@ -47,11 +47,9 @@ #define RTS51X_DESC "Realtek RTS5139/29 USB card reader driver" #define RTS51X_NAME "rts5139" #define RTS51X_CTL_THREAD "rts5139-control" -#define RTS51X_SCAN_THREAD "rts5139-scan" #define RTS51X_POLLING_THREAD "rts5139-polling" #define POLLING_IN_THREAD -/* #define SCSI_SCAN_DELAY */ #define SUPPORT_FILE_OP #define wait_timeout_x(task_state, msecs) \ @@ -66,8 +64,6 @@ do { \ /* Size of the DMA-mapped I/O buffer */ #define RTS51X_IOBUF_SIZE 1024 -/* Size of the autosense data buffer */ -#define RTS51X_SENSE_SIZE 18 /* Dynamic bitflag definitions (dflags): used in set_bit() etc. */ #define FLIDX_URB_ACTIVE 0 /* current_urb is in use */ @@ -76,7 +72,6 @@ do { \ #define FLIDX_DISCONNECTING 3 /* disconnect in progress */ #define FLIDX_RESETTING 4 /* device reset in progress */ #define FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ -#define FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ struct rts51x_chip; @@ -116,10 +111,6 @@ struct rts51x_usb { struct completion control_exit; /* control thread exit */ struct completion polling_exit; /* polling thread exit */ struct completion notify; /* thread begin/end */ -#ifdef SCSI_SCAN_DELAY - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct completion scanning_done; /* wait for scan thread */ -#endif }; extern struct usb_driver rts51x_driver; @@ -188,7 +179,6 @@ enum xfer_buf_dir { TO_XFER_BUF, FROM_XFER_BUF }; /* General routines provided by the usb-storage standard core */ #ifdef CONFIG_PM -void rts51x_try_to_enter_ss(struct rts51x_chip *chip); void rts51x_try_to_exit_ss(struct rts51x_chip *chip); int rts51x_suspend(struct usb_interface *iface, pm_message_t message); int rts51x_resume(struct usb_interface *iface); diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 424a845..4192c3b 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -37,7 +37,6 @@ #include "rts51x_chip.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "xd.h" #include "sd.h" #include "ms.h" @@ -94,7 +93,7 @@ void do_remaining_work(struct rts51x_chip *chip) ms_cleanup_work(chip); } -void do_reset_xd_card(struct rts51x_chip *chip) +static void do_reset_xd_card(struct rts51x_chip *chip) { int retval; @@ -148,7 +147,7 @@ void do_reset_sd_card(struct rts51x_chip *chip) } } -void do_reset_ms_card(struct rts51x_chip *chip) +static void do_reset_ms_card(struct rts51x_chip *chip) { int retval; @@ -175,7 +174,7 @@ void do_reset_ms_card(struct rts51x_chip *chip) } } -void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, +static void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, u8 *need_release) { int retval; @@ -191,7 +190,6 @@ void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, goto Exit_Debounce; if (chip->card_exist) { - rts51x_clear_start_time(chip); retval = rts51x_read_register(chip, CARD_INT_PEND, &value); if (retval != STATUS_SUCCESS) { rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, @@ -214,17 +212,11 @@ void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, } } else { if (chip->card_status & XD_CD) { - rts51x_clear_start_time(chip); reset_map |= XD_CARD; } else if (chip->card_status & SD_CD) { - rts51x_clear_start_time(chip); reset_map |= SD_CARD; } else if (chip->card_status & MS_CD) { - rts51x_clear_start_time(chip); reset_map |= MS_CARD; - } else { - if (rts51x_check_start_time(chip)) - rts51x_set_start_time(chip); } } @@ -709,7 +701,7 @@ u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun) return 0; } -int card_share_mode(struct rts51x_chip *chip, int card) +static int card_share_mode(struct rts51x_chip *chip, int card) { u8 value; @@ -823,22 +815,6 @@ int enable_card_clock(struct rts51x_chip *chip, u8 card) return STATUS_SUCCESS; } -int disable_card_clock(struct rts51x_chip *chip, u8 card) -{ - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); - - return STATUS_SUCCESS; -} - int card_power_on(struct rts51x_chip *chip, u8 card) { u8 mask, val1, val2; @@ -851,16 +827,7 @@ int card_power_on(struct rts51x_chip *chip, u8 card) if ((card == SD_CARD) || (card == XD_CARD)) { RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask | LDO3318_PWR_MASK, val1 | LDO_SUSPEND); - /* RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - LDO3318_PWR_MASK, LDO_SUSPEND); */ } - /* else if(card==XD_CARD) - { - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - mask|LDO3318_PWR_MASK, val1|LDO_SUSPEND); - //RTS51X_WRITE_REG(chip, CARD_PWR_CTL, - // LDO3318_PWR_MASK, LDO_SUSPEND); - } */ else { #endif RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val1); @@ -879,17 +846,6 @@ int card_power_on(struct rts51x_chip *chip, u8 card) return STATUS_SUCCESS; } -int card_power_off(struct rts51x_chip *chip, u8 card) -{ - u8 mask, val; - - mask = POWER_MASK; - val = POWER_OFF; - RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val); - - return STATUS_SUCCESS; -} - int monitor_card_cd(struct rts51x_chip *chip, u8 card) { int retval; diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index ac3c1e7..c5c03cc 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -204,13 +204,7 @@ /* LDO_POWER_CFG */ #define TUNE_SD18_MASK 0x1C -#define TUNE_SD18_1V7 0x00 #define TUNE_SD18_1V8 (0x01 << 2) -#define TUNE_SD18_1V9 (0x02 << 2) -#define TUNE_SD18_2V0 (0x03 << 2) -#define TUNE_SD18_2V7 (0x04 << 2) -#define TUNE_SD18_2V8 (0x05 << 2) -#define TUNE_SD18_2V9 (0x06 << 2) #define TUNE_SD18_3V3 (0x07 << 2) /* XD_CP_WAITTIME */ @@ -744,9 +738,7 @@ int monitor_card_cd(struct rts51x_chip *chip, u8 card); void do_remaining_work(struct rts51x_chip *chip); -void do_reset_xd_card(struct rts51x_chip *chip); void do_reset_sd_card(struct rts51x_chip *chip); -void do_reset_ms_card(struct rts51x_chip *chip); void rts51x_init_cards(struct rts51x_chip *chip); void rts51x_release_cards(struct rts51x_chip *chip); int switch_ssc_clock(struct rts51x_chip *chip, int clk); @@ -754,15 +746,12 @@ int switch_normal_clock(struct rts51x_chip *chip, int clk); int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, u16 sec_cnt); u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun); -int card_share_mode(struct rts51x_chip *chip, int card); int rts51x_select_card(struct rts51x_chip *chip, int card); void eject_card(struct rts51x_chip *chip, unsigned int lun); void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size); int enable_card_clock(struct rts51x_chip *chip, u8 card); -int disable_card_clock(struct rts51x_chip *chip, u8 card); int card_power_on(struct rts51x_chip *chip, u8 card); -int card_power_off(struct rts51x_chip *chip, u8 card); int toggle_gpio(struct rts51x_chip *chip, u8 gpio); int turn_on_led(struct rts51x_chip *chip, u8 gpio); int turn_off_led(struct rts51x_chip *chip, u8 gpio); diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index b3e0bb2..db88d7a 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -34,7 +34,6 @@ #include "rts51x_chip.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "xd.h" #include "ms.h" #include "sd.h" @@ -79,20 +78,18 @@ int rts51x_reset_chip(struct rts51x_chip *chip) chip->option.sd20_pad_drive); if (chip->rts5179) rts51x_write_register(chip, CARD_PULL_CTL5, 0x03, 0x01); - if (!chip->option.ww_enable) { - if (CHECK_PKG(chip, LQFP48)) { - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0xf0, 0xA0); - } else { - rts51x_write_register(chip, CARD_PULL_CTL1, - 0x30, 0x20); - rts51x_write_register(chip, CARD_PULL_CTL3, - 0x80, 0x80); - rts51x_write_register(chip, CARD_PULL_CTL6, - 0x0c, 0x08); - } + if (CHECK_PKG(chip, LQFP48)) { + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0xf0, 0xA0); + } else { + rts51x_write_register(chip, CARD_PULL_CTL1, + 0x30, 0x20); + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0x0c, 0x08); } } if (chip->option.sd_ctl & SUPPORT_UHS50_MMC44) { @@ -121,12 +118,6 @@ int rts51x_reset_chip(struct rts51x_chip *chip) /* GPIO OE */ rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO, GPIO_OE, GPIO_OE); -#ifdef LED_AUTO_BLINK - /* LED autoblink */ - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_AUTO_BLINK, - BLINK_ENABLE | BLINK_SPEED_MASK, - BLINK_ENABLE | chip->option.led_blink_speed); -#endif rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL); @@ -144,7 +135,6 @@ int rts51x_reset_chip(struct rts51x_chip *chip) card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); wait_timeout(10); } - rts51x_clear_start_time(chip); return STATUS_SUCCESS; } @@ -164,12 +154,6 @@ int rts51x_init_chip(struct rts51x_chip *chip) chip->card_ejected = 0; chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; -#if 0 - chip->option.sdr50_tx_phase = 0x01; - chip->option.sdr50_rx_phase = 0x05; - chip->option.ddr50_tx_phase = 0x09; - chip->option.ddr50_rx_phase = 0x06; /* add for debug */ -#endif #ifdef CLOSE_SSC_POWER rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, SSC_POWER_ON); udelay(100); @@ -178,9 +162,6 @@ int rts51x_init_chip(struct rts51x_chip *chip) RTS51X_SET_STAT(chip, STAT_RUN); RTS51X_READ_REG(chip, HW_VERSION, &val); - if ((val & 0x0f) >= 2) - chip->option.rcc_bug_fix_en = 0; - RTS51X_DEBUGP("rcc bug fix enable:%d\n", chip->option.rcc_bug_fix_en); RTS51X_DEBUGP("HW_VERSION: 0x%x\n", val); if (val & FPGA_VER) { chip->asic_code = 0; @@ -237,7 +218,6 @@ int rts51x_release_chip(struct rts51x_chip *chip) return STATUS_SUCCESS; } -#ifndef LED_AUTO_BLINK static inline void rts51x_blink_led(struct rts51x_chip *chip) { /* Read/Write */ @@ -251,20 +231,6 @@ static inline void rts51x_blink_led(struct rts51x_chip *chip) } } } -#endif - -int rts51x_check_start_time(struct rts51x_chip *chip) -{ - return 0; -} - -void rts51x_set_start_time(struct rts51x_chip *chip) -{ -} - -void rts51x_clear_start_time(struct rts51x_chip *chip) -{ -} static void rts51x_auto_delink_cmd(struct rts51x_chip *chip) { @@ -287,7 +253,6 @@ static void rts51x_auto_delink_polling_cycle(struct rts51x_chip *chip) chip->option.delink_delay * 2) { if (chip->auto_delink_counter == chip->option.delink_delay) { - clear_first_install_mark(chip); if (chip->card_exist) { /* False card */ if (!chip->card_ejected) { @@ -321,91 +286,13 @@ static void rts51x_auto_delink(struct rts51x_chip *chip) } #else /* some of called funcs are not implemented, so comment it out */ -#if 0 -/* using precise time as delink time */ -static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) -{ - int retvalue = 0; - - retvalue = rts51x_get_card_status(chip, &chip->card_status); - /* get card CD status success and card CD not exist, - * then check whether delink */ - if ((retvalue == STATUS_SUCCESS) - && (!(chip->card_status & (SD_CD | MS_CD | XD_CD)))) { - if (rts51x_count_delink_time(chip) >= - chip->option.delink_delay) { - clear_first_install_mark(chip); - RTS51X_DEBUGP("No card inserted, do delink\n"); - /* sangdy2010-05-17:disable because there is error - * after SSC clock closed and card power - * has been closed before */ - /* rts51x_write_register(chip, CARD_PWR_CTL, - DV3318_AUTO_PWR_OFF, 0); */ - rts51x_auto_delink_cmd(chip); - } - /* card CD exist and not ready, then do force delink */ - if ((retvalue == STATUS_SUCCESS) - && (chip->card_status & (SD_CD | MS_CD | XD_CD))) { - /* if card is not ejected or safely remove, - * then do force delink */ - if (!chip->card_ejected) { - /* sangdy2010-11-16:polling at least 2 cycles - * then do force delink for card may force delink - * if card is extracted and insert quickly - * after ready. */ - if (chip->auto_delink_counter > 1) { - if (rts51x_count_delink_time(chip) > - chip->option.delink_delay * 2) { - RTS51X_DEBUGP("Try to do force" - "delink\n"); - rts51x_auto_delink_force_cmd(chip); - } - } - } - } - chip->auto_delink_counter++; -} -#else -static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) -{ -} -#endif - static void rts51x_auto_delink(struct rts51x_chip *chip) { - rts51x_auto_delink_precise_time(chip); } #endif void rts51x_polling_func(struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); - - if (sd_card->sd_erase_status) { - if (chip->card_exist & SD_CARD) { - u8 val; - rts51x_read_register(chip, SD_BUS_STAT, &val); - if (val & SD_DAT0_STATUS) { - /* Erase completed */ - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - - /* SD card should be reinited, - * so we release it here. */ - sd_cleanup_work(chip); - release_sd_card(chip); - chip->card_ready &= ~SD_CARD; - chip->card_exist &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - clear_bit(chip->card2lun[SD_CARD], - &(chip->lun_mc)); - } - } else { - sd_card->sd_erase_status = SD_NOT_ERASE; - } - } -#endif rts51x_init_cards(chip); @@ -431,9 +318,7 @@ void rts51x_polling_func(struct rts51x_chip *chip) if (!RTS51X_CHK_STAT(chip, STAT_IDLE)) { RTS51X_DEBUGP("Idle state!\n"); RTS51X_SET_STAT(chip, STAT_IDLE); -#ifndef LED_AUTO_BLINK chip->led_toggle_counter = 0; -#endif /* Idle state, turn off LED * to reduce power consumption */ if (chip->option.led_always_on @@ -467,9 +352,7 @@ void rts51x_polling_func(struct rts51x_chip *chip) switch (RTS51X_GET_STAT(chip)) { case STAT_RUN: -#ifndef LED_AUTO_BLINK rts51x_blink_led(chip); -#endif do_remaining_work(chip); break; @@ -484,7 +367,6 @@ void rts51x_polling_func(struct rts51x_chip *chip) rts51x_auto_delink(chip); } else { chip->auto_delink_counter = 0; - rts51x_clear_start_time(chip); } } @@ -831,7 +713,7 @@ void rts51x_do_before_power_down(struct rts51x_chip *chip) chip->cur_clk = 0; chip->card_exist = 0; chip->cur_card = 0; - if (chip->asic_code && !chip->option.ww_enable) { + if (chip->asic_code) { if (CHECK_PKG(chip, LQFP48)) { rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); rts51x_write_register(chip, CARD_PULL_CTL6, 0xf0, 0x50); @@ -863,16 +745,6 @@ void rts51x_prepare_run(struct rts51x_chip *chip) rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); } #endif -#if 0 - if (chip->option.ss_en && RTS51X_CHK_STAT(chip, STAT_SS)) { - rts51x_try_to_exit_ss(chip); - wait_timeout(100); - rts51x_init_chip(chip); - rts51x_init_cards(chip); - } - - RTS51X_SET_STAT(chip, STAT_RUN); -#endif } #ifdef _MSG_TRACE @@ -1017,24 +889,6 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, status[0x0F] = 0x00; } } -#ifdef SUPPORT_SD_LOCK - /* SD Lock/Unlock */ - if (card == SD_CARD) { - status[0x17] = 0x80; - if (sd_card->sd_erase_status) - status[0x17] |= 0x01; /* Under erasing */ - if (sd_card->sd_lock_status & SD_LOCKED) { - status[0x17] |= 0x02; /* Locked */ - status[0x07] |= 0x40; /* Read protected */ - } - if (sd_card->sd_lock_status & SD_PWD_EXIST) - status[0x17] |= 0x04; /* Contain PWD */ - } else { - status[0x17] = 0x00; - } - - RTS51X_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); -#endif /* Function 0 * Support Magic Gate, CPRM and PhyRegister R/W */ @@ -1044,12 +898,6 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, * Support OC LUN status & WP LUN status */ status[0x1A] = 0x28; - /* Function 7 */ -#ifdef SUPPORT_SD_LOCK - /* Support SD Lock/Unlock */ - status[0x1F] = 0x01; -#endif - /* Function 2 * Support OC LUN status & WP LUN status */ status[0x1A] = 0x28; diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 13fc2a4..6d395b6 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -39,12 +39,7 @@ #define SUPPORT_CPRM #define SUPPORT_MAGIC_GATE #define SUPPORT_MSXC -/* #define LED_AUTO_BLINK */ - -/* { wwang, 2010-07-26 - * Add support for SD lock/unlock */ -/* #define SUPPORT_SD_LOCK */ -/* } wwang, 2010-07-26 */ +#define USING_POLLING_CYCLE_DELINK #ifdef SUPPORT_MAGIC_GA /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICVTE */ @@ -63,7 +58,6 @@ #define SUPPORT_OCP #define MS_SPEEDUP -/* #define XD_SPEEDUP */ #define SD_XD_IO_FOLLOW_PWR @@ -81,7 +75,6 @@ #define MAX_ALLOWED_LUN_CNT 8 #define CMD_BUF_LEN 1024 -#define RSP_BUF_LEN 1024 #define POLLING_INTERVAL 50 /* 50ms */ #define XD_FREE_TABLE_CNT 1200 @@ -128,8 +121,6 @@ #endif #define STATUS_FAIL 1 -#define STATUS_READ_FAIL 2 -#define STATUS_WRITE_FAIL 3 #define STATUS_TIMEDOUT 4 #define STATUS_NOMEM 5 #define STATUS_TRANS_SHORT 6 @@ -139,8 +130,6 @@ #define IDLE_MAX_COUNT 10 #define POLLING_WAIT_CNT 1 -#define DELINK_DELAY 100 -#define LED_TOGGLE_INTERVAL 6 #define LED_GPIO 0 /* package */ @@ -157,8 +146,6 @@ #define TRANSPORT_GOOD 0 /* Transport good, command failed */ #define TRANSPORT_FAILED 1 -/* Command failed, no auto-sense */ -#define TRANSPORT_NO_SENSE 2 /* Transport bad (i.e. device dead) */ #define TRANSPORT_ERROR 3 @@ -195,7 +182,6 @@ struct trace_msg_t { #define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 #define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 #define SENSE_TYPE_MEDIA_WRITE_ERR 8 -#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 #define SENSE_TYPE_FORMAT_CMD_FAILED 10 #ifdef SUPPORT_MAGIC_GATE /* COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED */ @@ -207,83 +193,27 @@ struct trace_msg_t { /* WRITE ERROR */ #define SENSE_TYPE_MG_WRITE_ERR 0x0e #endif -#ifdef SUPPORT_SD_LOCK -/* FOR Locked SD card */ -#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 -#endif /*---- sense key ----*/ -#define ILI 0x20 /* ILI bit is on */ - -#define NO_SENSE 0x00 /* not exist sense key */ -#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ -#define NOT_READY 0x02 /* Logical unit is not ready */ -#define MEDIA_ERR 0x03 /* medium/data error */ -#define HARDWARE_ERR 0x04 /* hardware error */ #define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ -#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ -#define DAT_PRTCT 0x07 /* read/write is desable */ -#define BLNC_CHK 0x08 /* find blank/DOF in read */ - /* write to unblank area */ -#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ -#define ABRT_CMD 0x0b /* Target make the command in error */ -#define EQUAL 0x0c /* Search Data end with Equal */ -#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ -#define MISCMP 0x0e /* find inequality */ /*----------------------------------- SENSE_DATA -----------------------------------*/ -/*---- valid ----*/ -#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ -#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ /*---- error code ----*/ #define CUR_ERR 0x70 /* current error */ -#define DEF_ERR 0x71 /* specific command error */ /*---- sense key Infomation ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key infomation */ #define SKSV 0x80 #define CDB_ILLEGAL 0x40 -#define DAT_ILLEGAL 0x00 -#define BPV 0x08 -#define BIT_ILLEGAL0 0 /* bit0 is illegal */ -#define BIT_ILLEGAL1 1 /* bit1 is illegal */ -#define BIT_ILLEGAL2 2 /* bit2 is illegal */ -#define BIT_ILLEGAL3 3 /* bit3 is illegal */ -#define BIT_ILLEGAL4 4 /* bit4 is illegal */ -#define BIT_ILLEGAL5 5 /* bit5 is illegal */ -#define BIT_ILLEGAL6 6 /* bit6 is illegal */ -#define BIT_ILLEGAL7 7 /* bit7 is illegal */ /*---- ASC ----*/ -#define ASC_NO_INFO 0x00 -#define ASC_MISCMP 0x1d #define ASC_INVLD_CDB 0x24 -#define ASC_INVLD_PARA 0x26 -#define ASC_LU_NOT_READY 0x04 -#define ASC_WRITE_ERR 0x0c -#define ASC_READ_ERR 0x11 -#define ASC_LOAD_EJCT_ERR 0x53 -#define ASC_MEDIA_NOT_PRESENT 0x3A -#define ASC_MEDIA_CHANGED 0x28 -#define ASC_MEDIA_IN_PROCESS 0x04 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_LUN_NOT_SUPPORTED 0x25 /*---- ASQC ----*/ -#define ASCQ_NO_INFO 0x00 -#define ASCQ_MEDIA_IN_PROCESS 0x01 -#define ASCQ_MISCMP 0x00 #define ASCQ_INVLD_CDB 0x00 -#define ASCQ_INVLD_PARA 0x02 -#define ASCQ_LU_NOT_READY 0x02 -#define ASCQ_WRITE_ERR 0x02 -#define ASCQ_READ_ERR 0x00 -#define ASCQ_LOAD_EJCT_ERR 0x00 -#define ASCQ_WRITE_PROTECT 0x00 struct sense_data_t { unsigned char err_code; /* error code */ @@ -296,13 +226,13 @@ struct sense_data_t { unsigned char seg_no; /* segment No. */ unsigned char sense_key; /* byte5 : ILI */ /* bit3-0 : sense key */ - unsigned char info[4]; /* infomation */ + unsigned char info[4]; /* information */ unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific infomation */ + unsigned char cmd_info[4]; /* command specific information */ unsigned char asc; /* ASC */ unsigned char ascq; /* ASCQ */ unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3]; /* sense key specific infomation */ + unsigned char sns_key_info[3]; /* sense key specific information */ }; /* sd_ctl bit map */ @@ -323,8 +253,6 @@ struct sense_data_t { #define SUPPORT_UHS50_MMC44 0x40 struct rts51x_option { - u8 led_blink_speed; - int mspro_formatter_enable; /* card clock expected by user for fpga platform */ @@ -368,8 +296,6 @@ struct rts51x_option { int ss_en; /* Interval to enter SS from IDLE state (second) */ int ss_delay; - int needs_remote_wakeup; - u8 ww_enable; /* sangdy2010-08-03:add for remote wakeup */ /* Enable SSC clock */ int ssc_en; @@ -392,10 +318,7 @@ struct rts51x_option { /*if reset or rw fail,then set SD20 pad drive again */ u8 reset_or_rw_fail_set_pad_drive; - u8 rcc_fail_flag; /* add to indicate whether rcc bug happen */ - u8 rcc_bug_fix_en; /* if set,then support fixing rcc bug */ u8 debounce_num; /* debounce number */ - int polling_time; /* polling delay time */ u8 led_toggle_interval; /* used to control led toggle speed */ int xd_rwn_step; u8 sd_send_status_en; @@ -405,7 +328,7 @@ struct rts51x_option { u8 ddr50_rx_phase; u8 sdr50_tx_phase; u8 sdr50_rx_phase; - /* used to enable select sdr50 tx phase according to proportion. */ + /* used to enable select sdr50 tx phase according to proportion. */ u8 sdr50_phase_sel; u8 ms_errreg_fix; u8 reset_mmc_first; @@ -614,11 +537,6 @@ struct sd_info { u8 sd_reset_fail; /* sangdy2010-07-01 */ u8 sd_send_status_en; -#ifdef SUPPORT_SD_LOCK - u8 sd_lock_status; - u8 sd_erase_status; - u8 sd_lock_notify; -#endif }; #define MODE_512_SEQ 0x01 @@ -720,9 +638,8 @@ struct rts51x_chip { struct scsi_cmnd *srb; struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; -#ifndef LED_AUTO_BLINK int led_toggle_counter; -#endif + int ss_counter; int idle_counter; int auto_delink_counter; diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c index 6eaebb6..ef893c8 100644 --- a/drivers/staging/rts5139/rts51x_fop.c +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -234,12 +234,7 @@ ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, return 0; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ -int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) -#else long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -#endif { struct rts51x_chip *chip; struct sd_direct_cmnd cmnd; diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h index 94d75f0..eb45acf 100644 --- a/drivers/staging/rts5139/rts51x_fop.h +++ b/drivers/staging/rts5139/rts51x_fop.h @@ -50,12 +50,7 @@ ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos); ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos); -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ -int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); -#else long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -#endif #endif diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index 87c9cdc..e07a1f4 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -40,7 +40,6 @@ #include "rts51x_scsi.h" #include "rts51x_card.h" #include "rts51x_transport.h" -#include "rts51x_sys.h" #include "sd_cprm.h" #include "ms_mg.h" #include "trace.h" @@ -370,10 +369,6 @@ void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); break; - case SENSE_TYPE_FORMAT_IN_PROGRESS: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); - break; - case SENSE_TYPE_FORMAT_CMD_FAILED: set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); break; @@ -396,12 +391,6 @@ void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) break; #endif -#ifdef SUPPORT_SD_LOCK - case SENSE_TYPE_MEDIA_READ_FORBIDDEN: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); - break; -#endif - case SENSE_TYPE_NO_SENSE: default: set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); @@ -448,20 +437,6 @@ static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip) set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); return TRANSPORT_FAILED; } -#ifdef SUPPORT_SD_LOCK - if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - if (sd_card->sd_lock_notify) { - sd_card->sd_lock_notify = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } else if (sd_card->sd_lock_status & SD_LOCKED) { - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif return TRANSPORT_GOOD; } @@ -797,9 +772,6 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif unsigned int lun = SCSI_LUN(srb); int retval; u32 start_sec; @@ -819,25 +791,6 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Accessing to any card is forbidden - * until the erase procedure of SD is completed */ - RTS51X_DEBUGP("SD card being erased!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (get_lun_card(chip, lun) == SD_CARD) { - if (sd_card->sd_lock_status & SD_LOCKED) { - RTS51X_DEBUGP("SD card locked!\n"); - set_sense_type(chip, lun, - SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { start_sec = ((u32) srb->cmnd[2] << 24) | @@ -883,20 +836,12 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = card_rw(srb, chip, start_sec, sec_cnt); if (retval != STATUS_SUCCESS) { -#if 0 - if (chip->need_release & chip->lun2card[lun]) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } else { -#endif if (srb->sc_data_direction == DMA_FROM_DEVICE) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); } else { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); } -#if 0 - } -#endif TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1516,7 +1461,7 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) } #ifdef SUPPORT_PCGL_1P18 -int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -1677,7 +1622,7 @@ static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) #endif #ifdef SUPPORT_MAGIC_GATE -int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -1764,7 +1709,7 @@ int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) return TRANSPORT_GOOD; } -int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); @@ -1871,30 +1816,10 @@ int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) { -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif struct ms_info *ms_card = &(chip->ms_card); unsigned int lun = SCSI_LUN(srb); int result = TRANSPORT_GOOD; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Block all SCSI command except for REQUEST_SENSE - * and rs_ppstatus */ - if (! - ((srb->cmnd[0] == VENDOR_CMND) - && (srb->cmnd[1] == SCSI_APP_CMD) - && (srb->cmnd[2] == GET_DEV_STATUS)) - && (srb->cmnd[0] != REQUEST_SENSE)) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, 0); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - if ((get_lun_card(chip, lun) == MS_CARD) && (ms_card->format_status == FORMAT_IN_PROGRESS)) { if ((srb->cmnd[0] != REQUEST_SENSE) @@ -1994,11 +1919,6 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) * Host functions ***********************************************************************/ -const char *host_info(struct Scsi_Host *host) -{ - return "SCSI emulation for RTS51xx USB driver-based card reader"; -} - int slave_alloc(struct scsi_device *sdev) { /* @@ -2111,14 +2031,7 @@ int queuecommand_lck(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) return 0; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ -int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) -{ - return queuecommand_lck(srb, done); -} -#else DEF_SCSI_QCMD(queuecommand) -#endif /*********************************************************************** * Error handling functions ***********************************************************************/ diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 3a8ca06..060d2c2 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -145,16 +145,11 @@ struct Scsi_Host; struct scsi_device; struct scsi_cmnd; -const char *host_info(struct Scsi_Host *host); int slave_alloc(struct scsi_device *sdev); int slave_configure(struct scsi_device *sdev); int proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout); -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ -int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)); -#else int queuecommand(struct Scsi_Host *, struct scsi_cmnd *); -#endif int command_abort(struct scsi_cmnd *srb); int device_reset(struct scsi_cmnd *srb); int bus_reset(struct scsi_cmnd *srb); diff --git a/drivers/staging/rts5139/rts51x_sys.h b/drivers/staging/rts5139/rts51x_sys.h deleted file mode 100644 index b09cd34..0000000 --- a/drivers/staging/rts5139/rts51x_sys.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Driver for Realtek USB RTS51xx card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - * Maintainer: - * Edwin Rong (edwin_rong@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTS51X_SYS_H -#define __RTS51X_SYS_H - -#include "rts51x.h" -#include "rts51x_chip.h" -#include "rts51x_card.h" - -#define USING_POLLING_CYCLE_DELINK - -extern int rts51x_check_start_time(struct rts51x_chip *chip); -extern void rts51x_set_start_time(struct rts51x_chip *chip); -extern void rts51x_clear_start_time(struct rts51x_chip *chip); - -/* typedef dma_addr_t ULONG_PTR; */ - -static inline void rts51x_reset_detected_cards(struct rts51x_chip *chip) -{ -/* rts51x_reset_cards(chip); */ -} - -static inline void clear_first_install_mark(struct rts51x_chip *chip) -{ -} - -void rts51x_enter_ss(struct rts51x_chip *chip); -void rts51x_exit_ss(struct rts51x_chip *chip); - -#endif /* __RTS51X_SYS_H */ diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c index da9c83b..89e4d80 100644 --- a/drivers/staging/rts5139/rts51x_transport.c +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -120,7 +120,7 @@ unsigned int rts51x_access_sglist(unsigned char *buffer, return cnt; } -unsigned int rts51x_access_xfer_buf(unsigned char *buffer, +static unsigned int rts51x_access_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr, unsigned int *offset, enum xfer_buf_dir dir) @@ -252,6 +252,8 @@ static int rts51x_msg_common(struct rts51x_chip *chip, struct urb *urb, return status; } +static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); + /* * Interpret the results of a URB transfer */ @@ -359,7 +361,7 @@ int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, rts51x->current_urb->actual_length); } -int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) +static int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) { int result; int endp = usb_pipeendpoint(pipe); @@ -378,11 +380,6 @@ int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) return STATUS_SUCCESS; } -int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe) -{ - return rts51x_clear_halt(chip, pipe); -} - static void rts51x_sg_clean(struct usb_sg_request *io) { if (io->urbs) { @@ -391,226 +388,17 @@ static void rts51x_sg_clean(struct usb_sg_request *io) kfree(io->urbs); io->urbs = NULL; } -#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ - if (io->dev->dev.dma_mask != NULL) - usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe), - io->sg, io->nents); -#endif io->dev = NULL; } -#if 0 -static void rts51x_sg_complete(struct urb *urb) -{ - struct usb_sg_request *io = urb->context; - int status = urb->status; - - spin_lock(&io->lock); - - /* In 2.5 we require hcds' endpoint queues not to progress after fault - * reports, until the completion callback (this!) returns. That lets - * device driver code (like this routine) unlink queued urbs first, - * if it needs to, since the HC won't work on them at all. So it's - * not possible for page N+1 to overwrite page N, and so on. - * - * That's only for "hard" faults; "soft" faults (unlinks) sometimes - * complete before the HCD can get requests away from hardware, - * though never during cleanup after a hard fault. - */ - if (io->status - && (io->status != -ECONNRESET - || status != -ECONNRESET) - && urb->actual_length) { - dev_err(io->dev->bus->controller, - "dev %s ep%d%s scatterlist error %d/%d\n", - io->dev->devpath, - usb_endpoint_num(&urb->ep->desc), - usb_urb_dir_in(urb) ? "in" : "out", - status, io->status); - /* BUG (); */ - } - - if (io->status == 0 && status && status != -ECONNRESET) { - int i, found, retval; - - io->status = status; - - /* the previous urbs, and this one, completed already. - * unlink pending urbs so they won't rx/tx bad data. - * careful: unlink can sometimes be synchronous... - */ - spin_unlock(&io->lock); - for (i = 0, found = 0; i < io->entries; i++) { - if (!io->urbs[i] || !io->urbs[i]->dev) - continue; - if (found) { - retval = usb_unlink_urb(io->urbs[i]); - if (retval != -EINPROGRESS && - retval != -ENODEV && - retval != -EBUSY) - dev_err(&io->dev->dev, - "%s, unlink --> %d\n", - __func__, retval); - } else if (urb == io->urbs[i]) - found = 1; - } - spin_lock(&io->lock); - } - urb->dev = NULL; - - /* on the last completion, signal usb_sg_wait() */ - io->bytes += urb->actual_length; - io->count--; - if (!io->count) - complete(&io->complete); - - spin_unlock(&io->lock); -} - -/* This function is ported from usb_sg_init, which can transfer - * sg list partially */ -int rts51x_sg_init_partial(struct usb_sg_request *io, struct usb_device *dev, - unsigned pipe, unsigned period, void *buf, struct scatterlist **sgptr, - unsigned int *offset, int nents, size_t length, gfp_t mem_flags) -{ - int i; - int urb_flags; - int dma; - struct scatterlist *sg = *sgptr, *first_sg; - - first_sg = (struct scatterlist *)buf; - if (!sg) - sg = first_sg; - - if (!io || !dev || !sg - || usb_pipecontrol(pipe) - || usb_pipeisoc(pipe) - || (nents <= 0)) - return -EINVAL; - - spin_lock_init(&io->lock); - io->dev = dev; - io->pipe = pipe; - io->sg = first_sg; /* used by unmap */ - io->nents = nents; - - RTS51X_DEBUGP("Before map, sg address: 0x%x\n", (unsigned int)sg); - RTS51X_DEBUGP("Before map, dev address: 0x%x\n", (unsigned int)dev); - - /* not all host controllers use DMA (like the mainstream pci ones); - * they can use PIO (sl811) or be software over another transport. - */ - dma = (dev->dev.dma_mask != NULL); - if (dma) { - /* map the whole sg list, because here we only know the - * total nents */ - io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), - first_sg, nents); - } else { - io->entries = nents; - } - - /* initialize all the urbs we'll use */ - if (io->entries <= 0) - return io->entries; - - io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); - if (!io->urbs) - goto nomem; - - urb_flags = URB_NO_INTERRUPT; - if (dma) - urb_flags |= URB_NO_TRANSFER_DMA_MAP; - if (usb_pipein(pipe)) - urb_flags |= URB_SHORT_NOT_OK; - - RTS51X_DEBUGP("io->entries = %d\n", io->entries); - - for (i = 0; (sg != NULL) && (length > 0); i++) { - unsigned len; - - RTS51X_DEBUGP("sg address: 0x%x\n", (unsigned int)sg); - RTS51X_DEBUGP("length = %d, *offset = %d\n", length, *offset); - - io->urbs[i] = usb_alloc_urb(0, mem_flags); - if (!io->urbs[i]) { - io->entries = i; - goto nomem; - } - - io->urbs[i]->dev = NULL; - io->urbs[i]->pipe = pipe; - io->urbs[i]->interval = period; - io->urbs[i]->transfer_flags = urb_flags; - - io->urbs[i]->complete = rts51x_sg_complete; - io->urbs[i]->context = io; - - if (dma) { - io->urbs[i]->transfer_dma = - sg_dma_address(sg) + *offset; - len = sg_dma_len(sg) - *offset; - io->urbs[i]->transfer_buffer = NULL; - RTS51X_DEBUGP(" -- sg entry dma length = %d\n", - sg_dma_len(sg)); - } else { - /* hc may use _only_ transfer_buffer */ - io->urbs[i]->transfer_buffer = sg_virt(sg) + *offset; - len = sg->length - *offset; - RTS51X_DEBUGP(" -- sg entry length = %d\n", - sg->length); - } - - if (length >= len) { - *offset = 0; - io->urbs[i]->transfer_buffer_length = len; - length -= len; - sg = sg_next(sg); - } else { - *offset += length; - io->urbs[i]->transfer_buffer_length = length; - length = 0; - } - if (length == 0) - io->entries = i + 1; -#if 0 - if (length) { - len = min_t(unsigned, len, length); - length -= len; - if (length == 0) { - io->entries = i + 1; - *offset += len; - } else { - *offset = 0; - } - } -#endif - } - RTS51X_DEBUGP("In %s, urb count: %d\n", __func__, i); - io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; - - RTS51X_DEBUGP("sg address stored in sgptr: 0x%x\n", (unsigned int)sg); - *sgptr = sg; - - /* transaction state */ - io->count = io->entries; - io->status = 0; - io->bytes = 0; - init_completion(&io->complete); - return 0; -nomem: - rts51x_sg_clean(io); - return -ENOMEM; -} -#endif -int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, +static int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, unsigned pipe, unsigned period, struct scatterlist *sg, int nents, size_t length, gfp_t mem_flags) { return usb_sg_init(io, dev, pipe, period, sg, nents, length, mem_flags); } -int rts51x_sg_wait(struct usb_sg_request *io, int timeout) +static int rts51x_sg_wait(struct usb_sg_request *io, int timeout) { long timeleft; int i; @@ -630,7 +418,7 @@ int rts51x_sg_wait(struct usb_sg_request *io, int timeout) */ spin_unlock_irq(&io->lock); switch (retval) { - /* maybe we retrying will recover */ + /* maybe the retry will recover */ case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: @@ -740,56 +528,9 @@ static int rts51x_bulk_transfer_sglist(struct rts51x_chip *chip, return interpret_urb_result(chip, pipe, length, result, chip->usb->current_sg.bytes); } -#if 0 -static int rts51x_bulk_transfer_sglist_partial(struct rts51x_chip *chip, - unsigned int pipe, void *buf, struct scatterlist **sgptr, - unsigned int *offset, int num_sg, unsigned int length, - unsigned int *act_len, int timeout) -{ - int result; - - /* don't submit s-g requests during abort processing */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) - TRACE_RET(chip, STATUS_ERROR); - /* initialize the scatter-gather request block */ - RTS51X_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, - length, num_sg); - result = rts51x_sg_init_partial(&chip->usb->current_sg, - chip->usb->pusb_dev, pipe, 0, buf, sgptr, offset, - num_sg, length, GFP_NOIO); - if (result) { - RTS51X_DEBUGP("rts51x_sg_init_partial returned %d\n", result); - TRACE_RET(chip, STATUS_ERROR); - } - - /* since the block has been initialized successfully, it's now - * okay to cancel it */ - set_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* did an abort occur during the submission? */ - if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) { - - /* cancel the request, if it hasn't been cancelled already */ - if (test_and_clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags)) { - RTS51X_DEBUGP("-- cancelling sg request\n"); - usb_sg_cancel(&chip->usb->current_sg); - } - } - - /* wait for the completion of the transfer */ - result = rts51x_sg_wait(&chip->usb->current_sg, timeout); - - clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); - - /* result = us->current_sg.status; */ - if (act_len) - *act_len = chip->usb->current_sg.bytes; - return interpret_urb_result(chip, pipe, length, result, - chip->usb->current_sg.bytes); -} -#endif -int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, unsigned int pipe, +static int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, + unsigned int pipe, void *buf, unsigned int length, unsigned int *act_len, int timeout) { @@ -860,11 +601,6 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, } kfree(tmp_buf); -#if 0 - result = rts51x_bulk_transfer_sglist_partial(chip, pipe, buf, - (struct scatterlist **)ptr, offset, - use_sg, len, act_len, timeout); -#endif } else { unsigned int step = 0; if (offset) diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h index 9dd556e..024f115 100644 --- a/drivers/staging/rts5139/rts51x_transport.h +++ b/drivers/staging/rts5139/rts51x_transport.h @@ -40,11 +40,6 @@ unsigned int rts51x_access_sglist(unsigned char *buffer, unsigned int buflen, void *sglist, void **sgptr, unsigned int *offset, enum xfer_buf_dir dir); -unsigned int rts51x_access_xfer_buf(unsigned char *buffer, unsigned int buflen, - struct scsi_cmnd *srb, - struct scatterlist **sgptr, - unsigned int *offset, - enum xfer_buf_dir dir); void rts51x_set_xfer_buf(unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb); void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, @@ -53,7 +48,6 @@ void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout); -int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, void *buf, unsigned int len, int use_sg, unsigned int *act_len, int timeout); @@ -62,12 +56,6 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, unsigned int len, int use_sg, unsigned int *act_len, int timeout); -/* whichPipe: - * 0: bulk in pipe - * 1: bulk out pipe - * 2: intr in pipe */ -int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe); - #ifndef POLLING_IN_THREAD int rts51x_start_epc_transfer(struct rts51x_chip *chip); void rts51x_cancel_epc_transfer(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c index d5dd2f9..b739f26 100644 --- a/drivers/staging/rts5139/sd.c +++ b/drivers/staging/rts5139/sd.c @@ -246,12 +246,7 @@ RTY_SEND_CMD: if (buf[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } -#ifdef SUPPORT_SD_LOCK - /* exclude bit25 CARD_IS_LOCKED */ - if (buf[1] & 0x7D) { -#else if (buf[1] & 0x7F) { -#endif RTS51X_DEBUGP("buf[1]: 0x%02x\n", buf[1]); TRACE_RET(chip, STATUS_FAIL); } @@ -709,37 +704,7 @@ int sd_select_card(struct rts51x_chip *chip, int select) return STATUS_SUCCESS; } -#ifdef SUPPORT_SD_LOCK -int sd_update_lock_status(struct rts51x_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 rsp[5]; - - retval = - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (rsp[1] & 0x02) - sd_card->sd_lock_status |= SD_LOCKED; - else - sd_card->sd_lock_status &= ~SD_LOCKED; - - RTS51X_DEBUGP("sd_card->sd_lock_status = 0x%x\n", - sd_card->sd_lock_status); - - if (rsp[1] & 0x01) { - /* LOCK_UNLOCK_FAILED */ - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} -#endif - -int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, +static int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, u8 rdychk, u16 pollingcnt) { struct sd_info *sd_card = &(chip->sd_card); @@ -1197,15 +1162,6 @@ static int sd_switch_function(struct rts51x_chip *chip, u8 bus_width) RTS51X_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_SDR_RST) - && (DDR50_SUPPORT == func_to_switch) - && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { - func_to_switch = SDR50_SUPPORT; - RTS51X_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); - } -#endif - if (func_to_switch) { retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, @@ -1562,7 +1518,7 @@ static u8 sd_search_final_phase(struct rts51x_chip *chip, u32 phase_map, } Search_Finish: - RTS51X_DEBUGP("Final choosen phase: %d\n", final_phase); + RTS51X_DEBUGP("Final chosen phase: %d\n", final_phase); return final_phase; } @@ -2024,10 +1980,6 @@ Switch_Fail: k = 0; hi_cap_flow = 0; support_1v8 = 0; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto SD_UNLOCK_ENTRY; -#endif retval = sd_prepare_reset(chip); if (retval != STATUS_SUCCESS) @@ -2182,7 +2134,7 @@ RTY_CMD55: sd_card->sd_addr += (u32) rsp[2] << 16; /* Get CSD register for Calculating Timing,Capacity, - * Check CSD to determaine as if this is the SD ROM card */ + * Check CSD to determine as if this is the SD ROM card */ retval = sd_check_csd(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -2190,20 +2142,6 @@ RTY_CMD55: retval = sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); -#ifdef SUPPORT_SD_LOCK -SD_UNLOCK_ENTRY: - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (sd_card->sd_lock_status & SD_LOCKED) { - sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); - return STATUS_SUCCESS; - } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } -#endif /* ACMD42 */ retval = @@ -2294,10 +2232,6 @@ SD_UNLOCK_ENTRY: if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); } -#ifdef SUPPORT_SD_LOCK - /* clear 1 bit mode status */ - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif if (CHK_SD30_SPEED(sd_card)) { rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, @@ -2380,19 +2314,6 @@ SD_UNLOCK_ENTRY: chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } -#endif - return STATUS_SUCCESS; } @@ -2587,17 +2508,10 @@ static int mmc_switch_timing_bus(struct rts51x_chip *chip) sd_card->capacity = ((u32) buf[5] << 24) | ((u32) buf[4] << 16) | ((u32) buf[3] << 8) | ((u32) buf[2]); -#ifdef SUPPORT_SD_LOCK - if (!(sd_card->sd_lock_status & SD_SDR_RST) && CHECK_UHS50(chip)) - card_type_mask = 0x07; - else - card_type_mask = 0x03; -#else if (CHECK_UHS50(chip)) card_type_mask = 0x07; else card_type_mask = 0x03; -#endif card_type = buf[1] & card_type_mask; if (card_type) { @@ -2626,15 +2540,9 @@ static int mmc_switch_timing_bus(struct rts51x_chip *chip) if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { SET_MMC_8BIT(sd_card); chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { SET_MMC_4BIT(sd_card); chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif } else { CLR_MMC_8BIT(sd_card); CLR_MMC_4BIT(sd_card); @@ -2652,11 +2560,6 @@ static int reset_mmc(struct rts51x_chip *chip) u8 change_to_ddr52 = 1; u8 cmd[5]; -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto MMC_UNLOCK_ENTRY; -#endif - MMC_DDR_FAIL: retval = sd_prepare_reset(chip); @@ -2745,7 +2648,7 @@ RTY_MMC_RST: TRACE_RET(chip, retval); /* Get CSD register for Calculating Timing,Capacity - * Check CSD to determaine as if this is the SD ROM card */ + * Check CSD to determine as if this is the SD ROM card */ retval = sd_check_csd(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -2763,13 +2666,6 @@ RTY_MMC_RST: 0); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); -#ifdef SUPPORT_SD_LOCK -MMC_UNLOCK_ENTRY: - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); -#endif RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); @@ -2842,18 +2738,6 @@ MMC_UNLOCK_ENTRY: } } } -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); - rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); - - retval = rts51x_send_cmd(chip, MODE_C, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } -#endif retval = rts51x_get_card_status(chip, &(chip->card_status)); if (retval != STATUS_SUCCESS) @@ -2879,11 +2763,6 @@ int reset_sd_card(struct rts51x_chip *chip) sd_card->capacity = 0; sd_card->sd_switch_fail = 0; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - sd_clear_reset_fail(chip); enable_card_clock(chip, SD_CARD); @@ -3006,7 +2885,7 @@ static int wait_data_buf_ready(struct rts51x_chip *chip) TRACE_RET(chip, STATUS_FAIL); } -void sd_stop_seq_mode(struct rts51x_chip *chip) +static void sd_stop_seq_mode(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -3300,7 +3179,7 @@ void sd_cleanup_work(struct rts51x_chip *chip) } } -inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) +static inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) { rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); @@ -3322,7 +3201,7 @@ inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) } } -int sd_power_off_card3v3(struct rts51x_chip *chip) +static int sd_power_off_card3v3(struct rts51x_chip *chip) { int retval; @@ -3346,17 +3225,12 @@ int release_sd_card(struct rts51x_chip *chip) struct sd_info *sd_card = &(chip->sd_card); int retval; - RTS51X_DEBUGP("elease_sd_card\n"); + RTS51X_DEBUGP("release_sd_card\n"); chip->card_ready &= ~SD_CARD; chip->card_fail &= ~SD_CARD; chip->card_wp &= ~SD_CARD; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - memset(sd_card->raw_csd, 0, 16); memset(sd_card->raw_scr, 0, 8); diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h index 0805edc..de155d8 100644 --- a/drivers/staging/rts5139/sd.h +++ b/drivers/staging/rts5139/sd.h @@ -141,29 +141,6 @@ #define SWITCH_MODE_ERR 0x06 #define SWITCH_PASS 0x07 -#ifdef SUPPORT_SD_LOCK -/* CMD42 Parameter */ -#define SD_ERASE 0x08 -#define SD_LOCK 0x04 -#define SD_UNLOCK 0x00 -#define SD_CLR_PWD 0x02 -#define SD_SET_PWD 0x01 - -#define SD_PWD_LEN 0x10 - -/* SD lock unlock Status */ -#define SD_LOCKED 0x80 /* Global lock status */ -#define SD_LOCK_1BIT_MODE 0x40 /**/ -#define SD_PWD_EXIST 0x20 -#define SD_UNLOCK_POW_ON 0x01 /**/ -#define SD_SDR_RST 0x02 /* Reset SD30 card with current DDR mode to SDR mode. */ -/* g_bySDEraseStatus */ -#define SD_NOT_ERASE 0x00 -#define SD_UNDER_ERASING 0x01 -#define SD_COMPLETE_ERASE 0x02 -/* SD_RW FAIL status */ -#define SD_RW_FORBIDDEN 0x0F /* read/write is forbidden (SD card) */ -#endif /* Function Group Definition */ /* Function Group 1 */ #define HS_SUPPORT 0x01 @@ -282,17 +259,11 @@ struct timing_phase_path { int sd_select_card(struct rts51x_chip *chip, int select); int reset_sd_card(struct rts51x_chip *chip); int sd_switch_clock(struct rts51x_chip *chip); -void sd_stop_seq_mode(struct rts51x_chip *chip); int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); void sd_cleanup_work(struct rts51x_chip *chip); -int sd_power_off_card3v3(struct rts51x_chip *chip); int release_sd_card(struct rts51x_chip *chip); -#ifdef SUPPORT_SD_LOCK -int sd_update_lock_status(struct rts51x_chip *chip); -#endif - #ifdef SUPPORT_CPRM extern int reset_sd(struct rts51x_chip *chip); extern int sd_check_data0_status(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index d5969d9..f8c6071 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -77,12 +77,7 @@ static inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) return STATUS_SUCCESS; } -int soft_reset_sd_card(struct rts51x_chip *chip) -{ - return reset_sd(chip); -} - -int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, +static int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) { @@ -206,11 +201,7 @@ RTY_SEND_CMD: if (buf[1] & 0x80) TRACE_RET(chip, STATUS_FAIL); } -#ifdef SUPPORT_SD_LOCK - if (buf[1] & 0x7D) { -#else if (buf[1] & 0x7F) { -#endif TRACE_RET(chip, STATUS_FAIL); } if (buf[2] & 0xF8) @@ -233,7 +224,7 @@ RTY_SEND_CMD: return STATUS_SUCCESS; } -int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) +static int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type) { int retval, rsp_len; u16 reg_addr; @@ -305,26 +296,8 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else /* Set H/W SD/MMC Bus Width */ rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); -#endif if (standby) { retval = sd_select_card(chip, 0); @@ -350,12 +323,6 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); } -#ifdef SUPPORT_SD_LOCK - /* Get SD lock status */ - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); -#endif return TRANSPORT_GOOD; @@ -399,21 +366,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } else { - bus_width = SD_BUS_WIDTH_4; - } - RTS51X_DEBUGP("bus_width = %d\n", bus_width); -#else bus_width = SD_BUS_WIDTH_4; -#endif if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, @@ -599,11 +552,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, int cmd13_checkbit = 0, write_err = 0; u8 rsp_type; u32 i; -#ifdef SUPPORT_SD_LOCK - int lock_cmd_fail = 0; - u8 sd_lock_state = 0; - u8 lock_cmd_type = 0; -#endif if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; @@ -614,12 +562,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - sd_lock_state = sd_card->sd_lock_status; - sd_lock_state &= SD_LOCKED; - } -#endif retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); if (retval != STATUS_SUCCESS) { @@ -631,25 +573,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, retval = sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = - rts51x_write_register(chip, SD_CFG1, 0x03, - SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); -#endif if (data_len < 512) { retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, @@ -692,10 +616,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, else memcpy(buf, data_buf, data_len); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) - lock_cmd_type = buf[0] & 0x0F; -#endif if (data_len > 256) { rts51x_init_cmd(chip); @@ -802,29 +722,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, SD_STOP | SD_CLR_ERR); TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (lock_cmd_type == SD_ERASE) { - sd_card->sd_erase_status = SD_UNDER_ERASING; - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - rts51x_init_cmd(chip); - rts51x_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, - SD_DAT0_STATUS); - retval = rts51x_send_cmd(chip, MODE_CR, 250); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - rts51x_get_rsp(chip, 1, 200); /* Don't care return value */ - - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { - RTS51X_DEBUGP("Lock command fail!\n"); - lock_cmd_fail = 1; - } - } -#endif /* SUPPORT_SD_LOCK */ if (standby) { retval = sd_select_card(chip, 1); @@ -865,51 +762,6 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, } if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (!lock_cmd_fail) { - RTS51X_DEBUGP("lock_cmd_type = 0x%x\n", - lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - if (lock_cmd_type & SD_SET_PWD) - sd_card->sd_lock_status |= SD_PWD_EXIST; - } - - RTS51X_DEBUGP("sd_lock_state = 0x%x," - "sd_card->sd_lock_status = 0x%x\n", - sd_lock_state, sd_card->sd_lock_status); - if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { - sd_card->sd_lock_notify = 1; - if (sd_lock_state) { - if (sd_card->sd_lock_status & - SD_LOCK_1BIT_MODE) { - sd_card->sd_lock_status |= - (SD_UNLOCK_POW_ON | SD_SDR_RST); - if (CHK_SD(sd_card)) { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status - &= ~(SD_UNLOCK_POW_ON | - SD_SDR_RST); - TRACE_GOTO(chip, - SD_Execute_Write_Cmd_Failed); - } - } - - sd_card->sd_lock_status &= - ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - } - } - } - } - - if (lock_cmd_fail) { - scsi_set_resid(srb, 0); - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - TRACE_RET(chip, TRANSPORT_FAILED); - } -#endif /* SUPPORT_SD_LOCK */ return TRANSPORT_GOOD; @@ -1173,30 +1025,18 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) switch (srb->cmnd[1] & 0x0F) { case 0: /* SD Card Power Off -> ON and Initialization */ -#ifdef SUPPORT_SD_LOCK - if (0x64 == srb->cmnd[9]) { - /* Command Mode */ - sd_card->sd_lock_status |= SD_SDR_RST; - } -#endif /* SUPPORT_SD_LOCK */ retval = reset_sd_card(chip); if (retval != STATUS_SUCCESS) { -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; TRACE_RET(chip, TRANSPORT_FAILED); } -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif break; case 1: /* reset CMD(CMD0) and Initialization * (without SD Card Power Off -> ON) */ - retval = soft_reset_sd_card(chip); + retval = reset_sd(chip); if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c index 5820605..58f8ba2 100644 --- a/drivers/staging/rts5139/xd.c +++ b/drivers/staging/rts5139/xd.c @@ -47,13 +47,6 @@ static inline void xd_set_err_code(struct rts51x_chip *chip, u8 err_code) xd_card->err_code = err_code; } -static inline int xd_check_err_code(struct rts51x_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &(chip->xd_card); - - return (xd_card->err_code == err_code); -} - static int xd_set_init_para(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); @@ -862,6 +855,8 @@ static void xd_set_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off, zone->l2p_table[log_off] = phy_off; } +static int xd_delay_write(struct rts51x_chip *chip); + static u32 xd_get_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off) { struct xd_info *xd_card = &(chip->xd_card); @@ -1182,91 +1177,6 @@ static int xd_copy_page(struct rts51x_chip *chip, return STATUS_SUCCESS; } -#ifdef XD_SPEEDUP -static int xd_auto_copy_page(struct rts51x_chip *chip, - u32 old_blk, u32 new_blk, - u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 old_page, new_page; - int retval; - u8 page_count; - - RTS51X_DEBUGP("Auto copy page from block 0x%x to block 0x%x\n", - old_blk, new_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - page_count = end_page - start_page; - - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) - TRACE_RET(chip, STATUS_FAIL); - - old_page = (old_blk << xd_card->block_shift) + start_page; - new_page = (new_blk << xd_card->block_shift) + start_page; - - XD_CLR_BAD_NEWBLK(xd_card); - - rts51x_init_cmd(chip); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WAITTIME, 0x03, WAIT_FF); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_PAGELEN, 0xFF, page_count); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR0, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR1, 0xFF, - (u8) old_page); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR2, 0xFF, - (u8) (old_page >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR3, 0xFF, - (u8) (old_page >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR4, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR0, 0xFF, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR1, 0xFF, - (u8) new_page); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR2, 0xFF, - (u8) (new_page >> 8)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR3, 0xFF, - (u8) (new_page >> 16)); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR4, 0xFF, 0); - - rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, - PINGPONG_BUFFER); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, - XD_BA_TRANSFORM | XD_ADDR_MASK, 0 | xd_card->addr_cycle); - - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, 0); - rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_COPY_PAGES); - rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, - XD_TRANSFER_END); - - retval = rts51x_send_cmd(chip, MODE_CR, 100); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_GOTO(chip, Copy_Fail); - } - - retval = rts51x_get_rsp(chip, 1, 800); - if (retval != STATUS_SUCCESS) { - rts51x_clear_xd_error(chip); - TRACE_GOTO(chip, Copy_Fail); - } - - return STATUS_SUCCESS; - -Copy_Fail: - retval = xd_copy_page(chip, old_blk, new_blk, start_page, end_page); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - return STATUS_SUCCESS; -} -#endif - static int xd_reset_cmd(struct rts51x_chip *chip) { int retval; @@ -1686,15 +1596,9 @@ Fail: XD_CLR_BAD_OLDBLK(xd_card); TRACE_RET(chip, STATUS_FAIL); } -#ifdef XD_SPEEDUP - retval = - xd_auto_copy_page(chip, phy_blk, new_blk, 0, - xd_card->page_off + 1); -#else retval = xd_copy_page(chip, phy_blk, new_blk, 0, xd_card->page_off + 1); -#endif if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); @@ -1741,13 +1645,8 @@ static int xd_finish_write(struct rts51x_chip *chip, TRACE_RET(chip, STATUS_FAIL); } } else { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, old_blk, new_blk, - page_off, xd_card->page_off + 1); -#else retval = xd_copy_page(chip, old_blk, new_blk, page_off, xd_card->page_off + 1); -#endif if (retval != STATUS_SUCCESS) { if (!XD_CHK_BAD_NEWBLK(xd_card)) { retval = xd_erase_block(chip, new_blk); @@ -1789,11 +1688,7 @@ static int xd_prepare_write(struct rts51x_chip *chip, old_blk, new_blk, log_blk, (int)page_off); if (page_off) { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, old_blk, new_blk, 0, page_off); -#else retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); -#endif if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); } @@ -1922,7 +1817,7 @@ Fail: TRACE_RET(chip, STATUS_FAIL); } -int xd_delay_write(struct rts51x_chip *chip) +static int xd_delay_write(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); @@ -1999,18 +1894,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, (start_page > delay_write->pageoff)) { delay_write->delay_write_flag = 0; if (delay_write->old_phyblock != BLK_NOT_FOUND) { -#ifdef XD_SPEEDUP - retval = xd_auto_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->pageoff, start_page); -#else retval = xd_copy_page(chip, delay_write->old_phyblock, delay_write->new_phyblock, delay_write->pageoff, start_page); -#endif if (retval != STATUS_SUCCESS) { set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); @@ -2198,7 +2086,7 @@ void xd_cleanup_work(struct rts51x_chip *chip) } } -int xd_power_off_card3v3(struct rts51x_chip *chip) +static int xd_power_off_card3v3(struct rts51x_chip *chip) { int retval; @@ -2232,7 +2120,7 @@ int release_xd_card(struct rts51x_chip *chip) struct xd_info *xd_card = &(chip->xd_card); int retval; - RTS51X_DEBUGP("elease_xd_card\n"); + RTS51X_DEBUGP("release_xd_card\n"); chip->card_ready &= ~XD_CARD; chip->card_fail &= ~XD_CARD; diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h index fa69590..55e4205 100644 --- a/drivers/staging/rts5139/xd.h +++ b/drivers/staging/rts5139/xd.h @@ -182,12 +182,10 @@ #define CIS1_9 (256 + 9) int reset_xd_card(struct rts51x_chip *chip); -int xd_delay_write(struct rts51x_chip *chip); int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); void xd_free_l2p_tbl(struct rts51x_chip *chip); void xd_cleanup_work(struct rts51x_chip *chip); -int xd_power_off_card3v3(struct rts51x_chip *chip); int release_xd_card(struct rts51x_chip *chip); #endif /* __RTS51X_XD_H */ diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index f9a4498..0bf6d95 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -4136,7 +4136,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) #else retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, 2, WAIT_INT, 0, 0, buf + 4, 1024); - if ((retval != STATUS_SUCCESS) || check_ms_err(chip) { + if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) { rtsx_clear_ms_error(chip); if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) { diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c index 9b2e5c9..54a4742 100644 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ b/drivers/staging/rts_pstor/rtsx_transport.c @@ -130,7 +130,7 @@ unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, /* Store the contents of buffer into srb's transfer buffer and set the * SCSI residue. */ void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; @@ -141,7 +141,7 @@ void rtsx_stor_set_xfer_buf(unsigned char *buffer, } void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) + unsigned int buflen, struct scsi_cmnd *srb) { unsigned int index = 0, offset = 0; diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index fa7c0d0..9d9fc7c 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -68,11 +68,11 @@ #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 /* flag that signifies tah the lock is -currently held by the proccess (struct file) */ +currently held by the process (struct file) */ #define SEP_DRIVER_OWN_LOCK_FLAG 1 /* flag that signifies tah the lock is currently NOT -held by the proccess (struct file) */ +held by the process (struct file) */ #define SEP_DRIVER_DISOWN_LOCK_FLAG 0 /* indicates whether driver has mapped/unmapped shared area */ @@ -280,7 +280,7 @@ held by the proccess (struct file) */ /* * Used to limit number of concurrent processes - * allowed to allocte dynamic buffers in fastcall + * allowed to allocate dynamic buffers in fastcall * interface. */ #define SEP_DOUBLEBUF_USERS_LIMIT 3 diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index f1701bc..df1d13e 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -786,7 +786,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) "[PID%d] poll: send_ct is %lx reply ct is %lx\n", current->pid, sep->send_ct, sep->reply_ct); - /* Check if error occured during poll */ + /* Check if error occurred during poll */ retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if ((retval2 != 0x0) && (retval2 != 0x8)) { dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n", @@ -1160,7 +1160,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, /* Put mapped kernel sg into kernel resource array */ - /* Set output params acording to the in_out flag */ + /* Set output params according to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = @@ -1358,7 +1358,7 @@ static int sep_lock_user_pages(struct sep_device *sep, lli_array[num_pages - 1].block_size); } - /* Set output params acording to the in_out flag */ + /* Set output params according to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = @@ -2038,7 +2038,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* * If this is not the last table - - * then allign it to the block size + * then align it to the block size */ if (!last_table_flag) table_data_size = @@ -3033,7 +3033,7 @@ static int sep_free_dcb_handler(struct sep_device *sep, * @cmd: command * @arg: pointer to argument structure * - * Implement the ioctl methods availble on the SEP device. + * Implement the ioctl methods available on the SEP device. */ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -4460,7 +4460,7 @@ static int sep_pm_runtime_suspend(struct device *dev) * @sep_pm_runtime_resume: resume- no communication with cpu & main memory * @sep_pm_runtime_suspend: suspend- no communication with cpu & main memory * @sep_pci_suspend: suspend - main memory is still ON - * @sep_pci_resume: resume - main meory is still ON + * @sep_pci_resume: resume - main memory is still ON */ static const struct dev_pm_ops sep_pm = { .runtime_resume = sep_pm_runtime_resume, diff --git a/drivers/staging/serial/68360serial.c b/drivers/staging/serial/68360serial.c deleted file mode 100644 index 23ee50e..0000000 --- a/drivers/staging/serial/68360serial.c +++ /dev/null @@ -1,2979 +0,0 @@ -/* - * UART driver for 68360 CPM SCC or SMC - * Copyright (c) 2000 D. Jeff Dionne <jeff@uclinux.org>, - * Copyright (c) 2000 Michael Leslie <mleslie@lineo.ca> - * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> - * - * I used the serial.c driver as the framework for this driver. - * Give credit to those guys. - * The original code was written for the MBX860 board. I tried to make - * it generic, but there may be some assumptions in the structures that - * have to be fixed later. - * To save porting time, I did not bother to change any object names - * that are not accessed outside of this file. - * It still needs lots of work........When it was easy, I included code - * to support the SCCs, but this has never been tested, nor is it complete. - * Only the SCCs support modem control, so that is not complete either. - * - * This module exports the following rs232 io functions: - * - * int rs_360_init(void); - */ - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/serialP.h> -#include <linux/major.h> -#include <linux/string.h> -#include <linux/fcntl.h> -#include <linux/ptrace.h> -#include <linux/mm.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <asm/irq.h> -#include <asm/m68360.h> -#include <asm/commproc.h> - - -#ifdef CONFIG_KGDB -extern void breakpoint(void); -extern void set_debug_traps(void); -extern int kgdb_output_string (const char* s, unsigned int count); -#endif - - -/* #ifdef CONFIG_SERIAL_CONSOLE */ /* This seems to be a post 2.0 thing - mles */ -#include <linux/console.h> -#include <linux/jiffies.h> - -/* this defines the index into rs_table for the port to use - */ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 1 /* ie SMC2 - note USE_SMC2 must be defined */ -#endif -/* #endif */ - -#if 0 -/* SCC2 for console - */ -#undef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 2 -#endif - - -#define TX_WAKEUP ASYNC_SHARE_IRQ - -static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.03"; - -static struct tty_driver *serial_driver; -int serial_console_setup(struct console *co, char *options); - -/* - * Serial driver configuration section. Here are the various options: - */ -#define SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define _INLINE_ inline - -#define DBG_CNT(s) - -/* We overload some of the items in the data structure to meet our - * needs. For example, the port address is the CPM parameter ram - * offset for the SCC or SMC. The maximum number of ports is 4 SCCs and - * 2 SMCs. The "hub6" field is used to indicate the channel number, with - * a flag indicating SCC or SMC, and the number is used as an index into - * the CPM parameter area for this device. - * The "type" field is currently set to 0, for PORT_UNKNOWN. It is - * not currently used. I should probably use it to indicate the port - * type of SMC or SCC. - * The SMCs do not support any modem control signals. - */ -#define smc_scc_num hub6 -#define NUM_IS_SCC ((int)0x00010000) -#define PORT_NUM(P) ((P) & 0x0000ffff) - - -#if defined (CONFIG_UCQUICC) - -volatile extern void *_periph_base; -/* sipex transceiver - * mode bits for are on pins - * - * SCC2 d16..19 - * SCC3 d20..23 - * SCC4 d24..27 - */ -#define SIPEX_MODE(n,m) ((m & 0x0f)<<(16+4*(n-1))) - -static uint sipex_mode_bits = 0x00000000; - -#endif - -/* There is no `serial_state' defined back here in 2.0. - * Try to get by with serial_struct - */ -/* #define serial_state serial_struct */ - -/* 2.4 -> 2.0 portability problem: async_icount in 2.4 has a few - * extras: */ - -#if 0 -struct async_icount_24 { - __u32 cts, dsr, rng, dcd, tx, rx; - __u32 frame, parity, overrun, brk; - __u32 buf_overrun; -} icount; -#endif - -#if 0 - -struct serial_state { - int magic; - int baud_base; - unsigned long port; - int irq; - int flags; - int hub6; - int type; - int line; - int revision; /* Chip revision (950) */ - int xmit_fifo_size; - int custom_divisor; - int count; - u8 *iomem_base; - u16 iomem_reg_shift; - unsigned short close_delay; - unsigned short closing_wait; /* time to wait before closing */ - struct async_icount_24 icount; - int io_type; - struct async_struct *info; -}; -#endif - -#define SSTATE_MAGIC 0x5302 - - - -/* SMC2 is sometimes used for low performance TDM interfaces. Define - * this as 1 if you want SMC2 as a serial port UART managed by this driver. - * Define this as 0 if you wish to use SMC2 for something else. - */ -#define USE_SMC2 1 - -#if 0 -/* Define SCC to ttySx mapping. */ -#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */ - -/* Define which SCC is the first one to use for a serial port. These - * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used - * for Ethernet, and the first available SCC for serial UART is SCC2. - * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and - * interrupt vectors in the table below to match. - */ -#define SCC_IDX_BASE 1 /* table index */ -#endif - - -/* Processors other than the 860 only get SMCs configured by default. - * Either they don't have SCCs or they are allocated somewhere else. - * Of course, there are now 860s without some SCCs, so we will need to - * address that someday. - * The Embedded Planet Multimedia I/O cards use TDM interfaces to the - * stereo codec parts, and we use SMC2 to help support that. - */ -static struct serial_state rs_table[] = { -/* type line PORT IRQ FLAGS smc_scc_num (F.K.A. hub6) */ - { 0, 0, PRSLOT_SMC1, CPMVEC_SMC1, 0, 0 } /* SMC1 ttyS0 */ -#if USE_SMC2 - ,{ 0, 0, PRSLOT_SMC2, CPMVEC_SMC2, 0, 1 } /* SMC2 ttyS1 */ -#endif - -#if defined(CONFIG_SERIAL_68360_SCC) - ,{ 0, 0, PRSLOT_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) } /* SCC2 ttyS2 */ - ,{ 0, 0, PRSLOT_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) } /* SCC3 ttyS3 */ - ,{ 0, 0, PRSLOT_SCC4, CPMVEC_SCC4, 0, (NUM_IS_SCC | 3) } /* SCC4 ttyS4 */ -#endif -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -/* The number of buffer descriptors and their sizes. - */ -#define RX_NUM_FIFO 4 -#define RX_BUF_SIZE 32 -#define TX_NUM_FIFO 4 -#define TX_BUF_SIZE 32 - -#define CONSOLE_NUM_FIFO 2 -#define CONSOLE_BUF_SIZE 4 - -char *console_fifos[CONSOLE_NUM_FIFO * CONSOLE_BUF_SIZE]; - -/* The async_struct in serial.h does not really give us what we - * need, so define our own here. - */ -typedef struct serial_info { - int magic; - int flags; - - struct serial_state *state; - /* struct serial_struct *state; */ - /* struct async_struct *state; */ - - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int timeout; - int line; - int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned long event; - unsigned long last_active; - int blocked_open; /* # of blocked opens */ - struct work_struct tqueue; - struct work_struct tqueue_hangup; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - -/* CPM Buffer Descriptor pointers. - */ - QUICC_BD *rx_bd_base; - QUICC_BD *rx_cur; - QUICC_BD *tx_bd_base; - QUICC_BD *tx_cur; -} ser_info_t; - - -/* since kmalloc_init() does not get called until much after this initialization: */ -static ser_info_t quicc_ser_info[NR_PORTS]; -static char rx_buf_pool[NR_PORTS * RX_NUM_FIFO * RX_BUF_SIZE]; -static char tx_buf_pool[NR_PORTS * TX_NUM_FIFO * TX_BUF_SIZE]; - -static void change_speed(ser_info_t *info); -static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout); - -static inline int serial_paranoia_check(ser_info_t *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * This is used to figure out the divisor speeds and the timeouts, - * indexed by the termio value. The generic CPM functions are responsible - * for setting and assigning baud rate generators for us. - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 }; - -/* This sucks. There is a better way: */ -#if defined(CONFIG_CONSOLE_9600) - #define CONSOLE_BAUDRATE 9600 -#elif defined(CONFIG_CONSOLE_19200) - #define CONSOLE_BAUDRATE 19200 -#elif defined(CONFIG_CONSOLE_115200) - #define CONSOLE_BAUDRATE 115200 -#else - #warning "console baud rate undefined" - #define CONSOLE_BAUDRATE 9600 -#endif - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_360_stop(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile struct scc_regs *sccp; - volatile struct smc_regs *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - local_irq_save(flags); - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm &= ~UART_SCCM_TX; - } else { - /* smcp = &cpmp->cp_smc[idx]; */ - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm &= ~SMCM_TX; - } - local_irq_restore(flags); -} - - -static void rs_360_start(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int idx; - unsigned long flags; - volatile struct scc_regs *sccp; - volatile struct smc_regs *smcp; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - local_irq_save(flags); - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm |= UART_SCCM_TX; - } else { - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm |= SMCM_TX; - } - local_irq_restore(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -static _INLINE_ void receive_chars(ser_info_t *info) -{ - struct tty_struct *tty = info->port.tty; - unsigned char ch, flag, *cp; - /*int ignored = 0;*/ - int i; - ushort status; - struct async_icount *icount; - /* struct async_icount_24 *icount; */ - volatile QUICC_BD *bdp; - - icount = &info->state->icount; - - /* Just loop through the closed BDs and copy the characters into - * the buffer. - */ - bdp = info->rx_cur; - for (;;) { - if (bdp->status & BD_SC_EMPTY) /* If this one is empty */ - break; /* we are all done */ - - /* The read status mask tell us what we should do with - * incoming characters, especially if errors occur. - * One special case is the use of BD_SC_EMPTY. If - * this is not set, we are supposed to be ignoring - * inputs. In this case, just mark the buffer empty and - * continue. - */ - if (!(info->read_status_mask & BD_SC_EMPTY)) { - bdp->status |= BD_SC_EMPTY; - bdp->status &= - ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->status & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - continue; - } - - /* Get the number of characters and the buffer pointer. - */ - i = bdp->length; - /* cp = (unsigned char *)__va(bdp->buf); */ - cp = (char *)bdp->buf; - status = bdp->status; - - while (i-- > 0) { - ch = *cp++; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, status); -#endif - flag = TTY_NORMAL; - - if (status & (BD_SC_BR | BD_SC_FR | - BD_SC_PR | BD_SC_OV)) { - /* - * For statistics only - */ - if (status & BD_SC_BR) - icount->brk++; - else if (status & BD_SC_PR) - icount->parity++; - else if (status & BD_SC_FR) - icount->frame++; - if (status & BD_SC_OV) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - if (status & info->ignore_status_mask) { - if (++ignored > 100) - break; - continue; - } - */ - status &= info->read_status_mask; - - if (status & (BD_SC_BR)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (status & BD_SC_PR) - flag = TTY_PARITY; - else if (status & BD_SC_FR) - flag = TTY_FRAME; - } - tty_insert_flip_char(tty, ch, flag); - if (status & BD_SC_OV) - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - - /* This BD is ready to be used again. Clear status. - * Get next BD. - */ - bdp->status |= BD_SC_EMPTY; - bdp->status &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); - - if (bdp->status & BD_SC_WRAP) - bdp = info->rx_bd_base; - else - bdp++; - } - - info->rx_cur = (QUICC_BD *)bdp; - - tty_schedule_flip(tty); -} - -static _INLINE_ void receive_break(ser_info_t *info) -{ - struct tty_struct *tty = info->port.tty; - - info->state->icount.brk++; - /* Check to see if there is room in the tty buffer for - * the break. If not, we exit now, losing the break. FIXME - */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); -} - -static _INLINE_ void transmit_chars(ser_info_t *info) -{ - - if ((info->flags & TX_WAKEUP) || - (info->port.tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) { - schedule_work(&info->tqueue); - } - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif -} - -#ifdef notdef - /* I need to do this for the SCCs, so it is left as a reminder. - */ -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - /* struct async_icount *icount; */ - struct async_icount_24 *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("scheduling hangup..."); -#endif - queue_task(&info->tqueue_hangup, - &tq_scheduler); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->port.tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->port.tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->port.tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} -#endif - -/* - * This is the serial driver's interrupt routine for a single port - */ -/* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */ -static void rs_360_interrupt(int vec, void *dev_id) -{ - u_char events; - int idx; - ser_info_t *info; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - info = dev_id; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - events = sccp->scc_scce; - if (events & SCCM_RX) - receive_chars(info); - if (events & SCCM_TX) - transmit_chars(info); - sccp->scc_scce = events; - } else { - smcp = &pquicc->smc_regs[idx]; - events = smcp->smc_smce; - if (events & SMCM_BRKE) - receive_break(info); - if (events & SMCM_RX) - receive_chars(info); - if (events & SMCM_TX) - transmit_chars(info); - smcp->smc_smce = events; - } - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d, %x)...", - info->state->smc_scc_num, events); -#endif -#ifdef modem_control - check_modem_status(info); -#endif - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - - -static void do_softint(void *private_) -{ - ser_info_t *info = (ser_info_t *) private_; - struct tty_struct *tty; - - tty = info->port.tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) - tty_wakeup(tty); -} - - -/* - * This routine is called from the scheduler tqueue when the interrupt - * routine has signalled that a hangup has occurred. The path of - * hangup processing is: - * - * serial interrupt routine -> (scheduler tqueue) -> - * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * - */ -static void do_serial_hangup(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->port.tty; - if (!tty) - return; - - tty_hangup(tty); -} - - -static int startup(ser_info_t *info) -{ - unsigned long flags; - int retval=0; - int idx; - /*struct serial_state *state = info->state;*/ - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - volatile struct smc_uart_pram *up; - volatile struct uart_pram *scup; - - - local_irq_save(flags); - - if (info->flags & ASYNC_INITIALIZED) { - goto errout; - } - -#ifdef maybe - if (!state->port || !state->type) { - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - goto errout; - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - -#ifdef modem_control - info->MCR = 0; - if (info->port.tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; -#endif - - if (info->port.tty) - clear_bit(TTY_IO_ERROR, &info->port.tty->flags); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - scup = &pquicc->pram[info->state->port].scc.pscc.u; - - scup->mrblr = RX_BUF_SIZE; - scup->max_idl = RX_BUF_SIZE; - - sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Enable interrupts and I/O. - */ - smcp->smc_smcm |= (SMCM_RX | SMCM_TX); - smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); - - /* We can tune the buffer length and idle characters - * to take advantage of the entire incoming buffer size. - * If mrblr is something other than 1, maxidl has to be - * non-zero or we never get an interrupt. The maxidl - * is the number of character times we wait after reception - * of the last character before we decide no more characters - * are coming. - */ - /* up = (smc_uart_t *)&pquicc->cp_dparam[state->port]; */ - /* holy unionized structures, Batman: */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - - up->mrblr = RX_BUF_SIZE; - up->max_idl = RX_BUF_SIZE; - - up->brkcr = 1; /* number of break chars */ - } - - info->flags |= ASYNC_INITIALIZED; - local_irq_restore(flags); - return 0; - -errout: - local_irq_restore(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(ser_info_t *info) -{ - unsigned long flags; - struct serial_state *state; - int idx; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - local_irq_save(flags); - - idx = PORT_NUM(state->smc_scc_num); - if (state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_gsmr.w.low &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) -#endif - sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Disable interrupts and I/O. - */ - smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); -#ifdef CONFIG_SERIAL_CONSOLE - /* We can't disable the transmitter if this is the - * system console. - */ - if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) -#endif - smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - } - - if (info->port.tty) - set_bit(TTY_IO_ERROR, &info->port.tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(ser_info_t *info) -{ - int baud_rate; - unsigned cflag, cval, scval, prev_mode; - int i, bits, sbits, idx; - unsigned long flags; - struct serial_state *state; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!info->port.tty || !info->port.tty->termios) - return; - cflag = info->port.tty->termios->c_cflag; - - state = info->state; - - /* Character length programmed into the mode register is the - * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, - * 1 or 2 stop bits, minus 1. - * The value 'bits' counts this for us. - */ - cval = 0; - scval = 0; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: bits = 5; break; - case CS6: bits = 6; break; - case CS7: bits = 7; break; - case CS8: bits = 8; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: bits = 8; break; - } - sbits = bits - 5; - - if (cflag & CSTOPB) { - cval |= SMCMR_SL; /* Two stops */ - scval |= SCU_PMSR_SL; - bits++; - } - if (cflag & PARENB) { - cval |= SMCMR_PEN; - scval |= SCU_PMSR_PEN; - bits++; - } - if (!(cflag & PARODD)) { - cval |= SMCMR_PM_EVEN; - scval |= (SCU_PMSR_REVP | SCU_PMSR_TEVP); - } - - /* Determine divisor based on baud rate */ - i = cflag & CBAUD; - if (i >= (sizeof(baud_table)/sizeof(int))) - baud_rate = 9600; - else - baud_rate = baud_table[i]; - - info->timeout = (TX_BUF_SIZE*HZ*bits); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - -#ifdef modem_control - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); -#endif - - /* - * Set up parity check flag - */ - info->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); - if (I_INPCK(info->port.tty)) - info->read_status_mask |= BD_SC_FR | BD_SC_PR; - if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty)) - info->read_status_mask |= BD_SC_BR; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= BD_SC_PR | BD_SC_FR; - if (I_IGNBRK(info->port.tty)) { - info->ignore_status_mask |= BD_SC_BR; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->port.tty)) - info->ignore_status_mask |= BD_SC_OV; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->read_status_mask &= ~BD_SC_EMPTY; - local_irq_save(flags); - - /* Start bit has not been added (so don't, because we would just - * subtract it later), and we need to add one for the number of - * stops bits (there is always at least one). - */ - bits++; - idx = PORT_NUM(state->smc_scc_num); - if (state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_psmr = (sbits << 12) | scval; - } else { - smcp = &pquicc->smc_regs[idx]; - - /* Set the mode register. We want to keep a copy of the - * enables, because we want to put them back if they were - * present. - */ - prev_mode = smcp->smc_smcmr; - smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); - } - - m360_cpm_setbrg((state - rs_table), baud_rate); - - local_irq_restore(flags); -} - -static void rs_360_put_char(struct tty_struct *tty, unsigned char ch) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile QUICC_BD *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - while (bdp->status & BD_SC_READY); - - /* *((char *)__va(bdp->buf)) = ch; */ - *((char *)bdp->buf) = ch; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (QUICC_BD *)bdp; - return 1; - -} - -static int rs_360_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - int c, ret = 0; - ser_info_t *info = (ser_info_t *)tty->driver_data; - volatile QUICC_BD *bdp; - -#ifdef CONFIG_KGDB - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(buf, count)) - return ret; -#endif - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty) - return 0; - - bdp = info->tx_cur; - - while (1) { - c = min(count, TX_BUF_SIZE); - - if (c <= 0) - break; - - if (bdp->status & BD_SC_READY) { - info->flags |= TX_WAKEUP; - break; - } - - /* memcpy(__va(bdp->buf), buf, c); */ - memcpy((void *)bdp->buf, buf, c); - - bdp->length = c; - bdp->status |= BD_SC_READY; - - buf += c; - count -= c; - ret += c; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - info->tx_cur = (QUICC_BD *)bdp; - } - return ret; -} - -static int rs_360_write_room(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - - if ((info->tx_cur->status & BD_SC_READY) == 0) { - info->flags &= ~TX_WAKEUP; - ret = TX_BUF_SIZE; - } - else { - info->flags |= TX_WAKEUP; - ret = 0; - } - return ret; -} - -/* I could track this with transmit counters....maybe later. -*/ -static int rs_360_chars_in_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return 0; -} - -static void rs_360_flush_buffer(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - - /* There is nothing to "flush", whatever we gave the CPM - * is on its way out. - */ - tty_wakeup(tty); - info->flags &= ~TX_WAKEUP; -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_360_send_xchar(struct tty_struct *tty, char ch) -{ - volatile QUICC_BD *bdp; - - ser_info_t *info = (ser_info_t *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - bdp = info->tx_cur; - while (bdp->status & BD_SC_READY); - - /* *((char *)__va(bdp->buf)) = ch; */ - *((char *)bdp->buf) = ch; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - /* Get next BD. - */ - if (bdp->status & BD_SC_WRAP) - bdp = info->tx_bd_base; - else - bdp++; - - info->tx_cur = (QUICC_BD *)bdp; -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_360_throttle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_360_send_xchar(tty, STOP_CHAR(tty)); - -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif -} - -static void rs_360_unthrottle(struct tty_struct * tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_360_send_xchar(tty, START_CHAR(tty)); - } -#ifdef modem_control - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -#ifdef maybe -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - - local_irq_disable(); - status = serial_in(info, UART_LSR); - local_irq_enable(); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} -#endif - -static int rs_360_tiocmget(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned int result = 0; -#ifdef modem_control - unsigned char control, status; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - control = info->MCR; - local_irq_disable(); - status = serial_in(info, UART_MSR); - local_irq_enable(); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); -#endif - return result; -} - -static int rs_360_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ -#ifdef modem_control - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned int arg; - - if (serial_paranoia_check(info, tty->name, __func__)) - return -ENODEV; - - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - /* FIXME: locking on info->mcr */ - if (set & TIOCM_RTS) - info->mcr |= UART_MCR_RTS; - if (set & TIOCM_DTR) - info->mcr |= UART_MCR_DTR; - if (clear & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (clear & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; - -#ifdef TIOCM_OUT1 - if (set & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (set & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; - if (clear & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (clear & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); -#endif - return 0; -} - -/* Sending a break is a two step process on the SMC/SCC. It is accomplished - * by sending a STOP TRANSMIT command followed by a RESTART TRANSMIT - * command. We take advantage of the begin/end functions to make this - * happen. - */ -static ushort smc_chan_map[] = { - CPM_CR_CH_SMC1, - CPM_CR_CH_SMC2 -}; - -static ushort scc_chan_map[] = { - CPM_CR_CH_SCC1, - CPM_CR_CH_SCC2, - CPM_CR_CH_SCC3, - CPM_CR_CH_SCC4 -}; - -static void begin_break(ser_info_t *info) -{ - volatile QUICC *cp; - ushort chan; - int idx; - - cp = pquicc; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) - chan = scc_chan_map[idx]; - else - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); -} - -static void end_break(ser_info_t *info) -{ - volatile QUICC *cp; - ushort chan; - int idx; - - cp = pquicc; - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) - chan = scc_chan_map[idx]; - else - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); -} - -/* - * This routine sends a break character out the serial port. - */ -static void send_break(ser_info_t *info, unsigned int duration) -{ -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("rs_send_break(%d) jiff=%lu...", duration, jiffies); -#endif - begin_break(info); - msleep_interruptible(duration); - end_break(info); -#ifdef SERIAL_DEBUG_SEND_BREAK - printk("done jiffies=%lu\n", jiffies); -#endif -} - - -/* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ -static int rs_360_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct async_icount cnow; - - local_irq_disable(); - cnow = info->state->icount; - local_irq_enable(); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - - return 0; -} - -static int rs_360_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - int error; - ser_info_t *info = (ser_info_t *)tty->driver_data; - int retval; - struct async_icount cnow; - /* struct async_icount_24 cnow;*/ /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if (cmd != TIOCMIWAIT) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TCSBRK: /* SVID version: non-zero arg --> no break */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - if (!arg) { - send_break(info, 250); /* 1/4 second */ - if (signal_pending(current)) - return -EINTR; - } - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (signal_pending(current)) - return -EINTR; - send_break(info, arg ? arg*100 : 250); - if (signal_pending(current)) - return -EINTR; - return 0; - case TIOCSBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - begin_break(info); - return 0; - case TIOCCBRK: - retval = tty_check_change(tty); - if (retval) - return retval; - end_break(info); - return 0; -#ifdef maybe - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); -#endif - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: -#ifdef modem_control - local_irq_disable(); - /* note the counters on entry */ - cprev = info->state->icount; - local_irq_enable(); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - local_irq_disable(); - cnow = info->state->icount; /* atomic copy */ - local_irq_enable(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ -#else - return 0; -#endif - - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* FIX UP modem control here someday...... -*/ -static void rs_360_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - - change_speed(info); - -#ifdef modem_control - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(tty->termios->c_cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (tty->termios->c_cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!tty->hw_stopped || - !(tty->termios->c_cflag & CRTSCTS)) { - info->MCR |= UART_MCR_RTS; - } - local_irq_disable(); - serial_out(info, UART_MCR, info->MCR); - local_irq_enable(); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_360_start(tty); - } -#endif - -#if 0 - /* - * No need to wake up processes in open wait, since they - * sample the CLOCAL flag once, and don't recheck it. - * XXX It's not clear whether the current behavior is correct - * or not. Hence, this may change..... - */ - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_360_close(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - /* struct async_state *state; */ - struct serial_state *state; - unsigned long flags; - int idx; - volatile struct smc_regs *smcp; - volatile struct scc_regs *sccp; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - local_irq_save(flags); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - local_irq_restore(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - local_irq_restore(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->read_status_mask &= ~BD_SC_EMPTY; - if (info->flags & ASYNC_INITIALIZED) { - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - sccp = &pquicc->scc_regs[idx]; - sccp->scc_sccm &= ~UART_SCCM_RX; - sccp->scc_gsmr.w.low &= ~SCC_GSMRL_ENR; - } else { - smcp = &pquicc->smc_regs[idx]; - smcp->smc_smcm &= ~SMCM_RX; - smcp->smc_smcmr &= ~SMCMR_REN; - } - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_360_wait_until_sent(tty, info->timeout); - } - shutdown(info); - rs_360_flush_buffer(tty); - tty_ldisc_flush(tty); - tty->closing = 0; - info->event = 0; - info->port.tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs(info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - local_irq_restore(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_360_wait_until_sent(struct tty_struct *tty, int timeout) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - unsigned long orig_jiffies, char_time; - /*int lsr;*/ - volatile QUICC_BD *bdp; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - -#ifdef maybe - if (info->state->type == PORT_UNKNOWN) - return; -#endif - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = 1; - if (timeout) - char_time = min(char_time, (unsigned long)timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - - /* We go through the loop at least once because we can't tell - * exactly when the last character exits the shifter. There can - * be at least two characters waiting to be sent after the buffers - * are empty. - */ - do { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif -/* current->counter = 0; make us low-priority */ - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && (time_after(jiffies, orig_jiffies + timeout))) - break; - /* The 'tx_cur' is really the next buffer to send. We - * have to back up to the previous BD and wait for it - * to go. This isn't perfect, because all this indicates - * is the buffer is available. There are still characters - * in the CPM FIFO. - */ - bdp = info->tx_cur; - if (bdp == info->tx_bd_base) - bdp += (TX_NUM_FIFO-1); - else - bdp--; - } while (bdp->status & BD_SC_READY); - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_360_hangup(struct tty_struct *tty) -{ - ser_info_t *info = (ser_info_t *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_360_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->port.tty = NULL; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - ser_info_t *info) -{ -#ifdef DO_THIS_LATER - DECLARE_WAITQUEUE(wait, current); -#endif - struct serial_state *state = info->state; - int retval; - int do_clocal = 0; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - * If this is an SMC port, we don't have modem control to wait - * for, so just get out here. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR)) || - !(info->state->smc_scc_num & NUM_IS_SCC)) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; -#ifdef DO_THIS_LATER - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - local_irq_disable(); - if (!tty_hung_up_p(filp)) - state->count--; - local_irq_enable(); - info->blocked_open++; - while (1) { - local_irq_disable(); - if (tty->termios->c_cflag & CBAUD) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - local_irq_enable(); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - tty_unlock(tty); - schedule(); - tty_lock(tty); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif -#endif /* DO_THIS_LATER */ - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, ser_info_t **ret_info) -{ - struct serial_state *sstate; - - sstate = rs_table + line; - if (sstate->info) { - sstate->count++; - *ret_info = (ser_info_t *)sstate->info; - return 0; - } - else { - return -ENOMEM; - } -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_360_open(struct tty_struct *tty, struct file * filp) -{ - ser_info_t *info; - int retval, line; - - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) - return -ENODEV; - retval = get_async_struct(line, &info); - if (retval) - return retval; - if (serial_paranoia_check(info, tty->name, "rs_open")) - return -ENODEV; - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - tty->driver_data = info; - info->port.tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ -#ifdef notdef - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; -#endif - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, - (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC", - (unsigned int)(state->port), state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - -#ifdef notdef - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->port.tty = NULL; - } - local_irq_disable(); - status = serial_in(info, UART_MSR); - control = info ? info->MCR : serial_in(info, UART_MCR); - local_irq_enable(); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); -#endif - return ret; -} - -int rs_360_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - len += line_info(page + len, &rs_table[i]); - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (begin-off); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s\n", serial_name, serial_version); -} - - -/* - * The serial console driver used during boot. Note that these names - * clash with those found in "serial.c", so we currently can't support - * the 16xxx uarts and these at the same time. I will fix this to become - * an indirect function call from tty_io.c (or something). - */ - -#ifdef CONFIG_SERIAL_CONSOLE - -/* - * Print a string to the serial port trying not to disturb any possible - * real use of the port... - */ -static void my_console_write(int idx, const char *s, - unsigned count) -{ - struct serial_state *ser; - ser_info_t *info; - unsigned i; - QUICC_BD *bdp, *bdbase; - volatile struct smc_uart_pram *up; - volatile u_char *cp; - - ser = rs_table + idx; - - - /* If the port has been initialized for general use, we have - * to use the buffer descriptors allocated there. Otherwise, - * we simply use the single buffer allocated. - */ - if ((info = (ser_info_t *)ser->info) != NULL) { - bdp = info->tx_cur; - bdbase = info->tx_bd_base; - } - else { - /* Pointer to UART in parameter ram. - */ - /* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */ - up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u; - - /* Get the address of the host memory buffer. - */ - bdp = bdbase = (QUICC_BD *)((uint)pquicc + (uint)up->tbase); - } - - /* - * We need to gracefully shut down the transmitter, disable - * interrupts, then send our bytes out. - */ - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while (bdp->status & BD_SC_READY); - - /* Send the character out. - */ - cp = bdp->buf; - *cp = *s; - - bdp->length = 1; - bdp->status |= BD_SC_READY; - - if (bdp->status & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while (bdp->status & BD_SC_READY); - /* cp = __va(bdp->buf); */ - cp = bdp->buf; - *cp = 13; - bdp->length = 1; - bdp->status |= BD_SC_READY; - - if (bdp->status & BD_SC_WRAP) { - bdp = bdbase; - } - else { - bdp++; - } - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while (bdp->status & BD_SC_READY); - - if (info) - info->tx_cur = (QUICC_BD *)bdp; -} - -static void serial_console_write(struct console *c, const char *s, - unsigned count) -{ -#ifdef CONFIG_KGDB - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(s, count)) - return; -#endif - my_console_write(c->index, s, count); -} - - - -/*void console_print_68360(const char *p) -{ - const char *cp = p; - int i; - - for (i=0;cp[i]!=0;i++); - - serial_console_write (p, i); - - //Comment this if you want to have a strict interrupt-driven output - //rs_fair_output(); - - return; -}*/ - - - - - - -#ifdef CONFIG_XMON -int -xmon_360_write(const char *s, unsigned count) -{ - my_console_write(0, s, count); - return(count); -} -#endif - -#ifdef CONFIG_KGDB -void -putDebugChar(char ch) -{ - my_console_write(0, &ch, 1); -} -#endif - -/* - * Receive character from the serial port. This only works well - * before the port is initialized for real use. - */ -static int my_console_wait_key(int idx, int xmon, char *obuf) -{ - struct serial_state *ser; - u_char c, *cp; - ser_info_t *info; - QUICC_BD *bdp; - volatile struct smc_uart_pram *up; - int i; - - ser = rs_table + idx; - - /* Get the address of the host memory buffer. - * If the port has been initialized for general use, we must - * use information from the port structure. - */ - if ((info = (ser_info_t *)ser->info)) - bdp = info->rx_cur; - else - /* bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase]; */ - bdp = (QUICC_BD *)((uint)pquicc + (uint)up->tbase); - - /* Pointer to UART in parameter ram. - */ - /* up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - - /* - * We need to gracefully shut down the receiver, disable - * interrupts, then read the input. - * XMON just wants a poll. If no character, return -1, else - * return the character. - */ - if (!xmon) { - while (bdp->status & BD_SC_EMPTY); - } - else { - if (bdp->status & BD_SC_EMPTY) - return -1; - } - - cp = (char *)bdp->buf; - - if (obuf) { - i = c = bdp->length; - while (i-- > 0) - *obuf++ = *cp++; - } - else { - c = *cp; - } - bdp->status |= BD_SC_EMPTY; - - if (info) { - if (bdp->status & BD_SC_WRAP) { - bdp = info->rx_bd_base; - } - else { - bdp++; - } - info->rx_cur = (QUICC_BD *)bdp; - } - - return((int)c); -} - -static int serial_console_wait_key(struct console *co) -{ - return(my_console_wait_key(co->index, 0, NULL)); -} - -#ifdef CONFIG_XMON -int -xmon_360_read_poll(void) -{ - return(my_console_wait_key(0, 1, NULL)); -} - -int -xmon_360_read_char(void) -{ - return(my_console_wait_key(0, 0, NULL)); -} -#endif - -#ifdef CONFIG_KGDB -static char kgdb_buf[RX_BUF_SIZE], *kgdp; -static int kgdb_chars; - -unsigned char -getDebugChar(void) -{ - if (kgdb_chars <= 0) { - kgdb_chars = my_console_wait_key(0, 0, kgdb_buf); - kgdp = kgdb_buf; - } - kgdb_chars--; - - return(*kgdp++); -} - -void kgdb_interruptible(int state) -{ -} -void kgdb_map_scc(void) -{ - struct serial_state *ser; - uint mem_addr; - volatile QUICC_BD *bdp; - volatile smc_uart_t *up; - - cpmp = (cpm360_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - - /* To avoid data cache CPM DMA coherency problems, allocate a - * buffer in the CPM DPRAM. This will work until the CPM and - * serial ports are initialized. At that time a memory buffer - * will be allocated. - * The port is already initialized from the boot procedure, all - * we do here is give it a different buffer and make it a FIFO. - */ - - ser = rs_table; - - /* Right now, assume we are using SMCs. - */ - up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; - - /* Allocate space for an input FIFO, plus a few bytes for output. - * Allocate bytes to maintain word alignment. - */ - mem_addr = (uint)(&cpmp->cp_dpmem[0x1000]); - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_rbase]; - bdp->buf = mem_addr; - - bdp = (QUICC_BD *)&cpmp->cp_dpmem[up->smc_tbase]; - bdp->buf = mem_addr+RX_BUF_SIZE; - - up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */ - up->smc_maxidl = RX_BUF_SIZE; -} -#endif - -static struct tty_struct *serial_console_device(struct console *c, int *index) -{ - *index = c->index; - return serial_driver; -} - - -struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .wait_key = serial_console_wait_key, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = CONFIG_SERIAL_CONSOLE_PORT, -}; - - - -/* - * Register console. - */ -long console_360_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - /*register_console (console_print_68360); - 2.0.38 only required a write - function pointer. */ - return kmem_start; -} - -#endif - -/* Index in baud rate table of the default console baud rate. -*/ -static int baud_idx; - -static const struct tty_operations rs_360_ops = { - .owner = THIS_MODULE, - .open = rs_360_open, - .close = rs_360_close, - .write = rs_360_write, - .put_char = rs_360_put_char, - .write_room = rs_360_write_room, - .chars_in_buffer = rs_360_chars_in_buffer, - .flush_buffer = rs_360_flush_buffer, - .ioctl = rs_360_ioctl, - .throttle = rs_360_throttle, - .unthrottle = rs_360_unthrottle, - /* .send_xchar = rs_360_send_xchar, */ - .set_termios = rs_360_set_termios, - .stop = rs_360_stop, - .start = rs_360_start, - .hangup = rs_360_hangup, - /* .wait_until_sent = rs_360_wait_until_sent, */ - /* .read_proc = rs_360_read_proc, */ - .tiocmget = rs_360_tiocmget, - .tiocmset = rs_360_tiocmset, - .get_icount = rs_360_get_icount, -}; - -static int __init rs_360_init(void) -{ - struct serial_state * state; - ser_info_t *info; - void *mem_addr; - uint dp_addr, iobits; - int i, j, idx; - ushort chan; - QUICC_BD *bdp; - volatile QUICC *cp; - volatile struct smc_regs *sp; - volatile struct smc_uart_pram *up; - volatile struct scc_regs *scp; - volatile struct uart_pram *sup; - /* volatile immap_t *immap; */ - - serial_driver = alloc_tty_driver(NR_PORTS); - if (!serial_driver) - return -1; - - show_serial_version(); - - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - baud_idx | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &rs_360_ops); - - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - cp = pquicc; /* Get pointer to Communication Processor */ - /* immap = (immap_t *)IMAP_ADDR; */ /* and to internal registers */ - - - /* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O. - */ - /* The "standard" configuration through the 860. - */ -/* immap->im_ioport.iop_papar |= 0x00fc; */ -/* immap->im_ioport.iop_padir &= ~0x00fc; */ -/* immap->im_ioport.iop_paodr &= ~0x00fc; */ - cp->pio_papar |= 0x00fc; - cp->pio_padir &= ~0x00fc; - /* cp->pio_paodr &= ~0x00fc; */ - - - /* Since we don't yet do modem control, connect the port C pins - * as general purpose I/O. This will assert CTS and CD for the - * SCC ports. - */ - /* FIXME: see 360um p.7-365 and 860um p.34-12 - * I can't make sense of these bits - mleslie*/ -/* immap->im_ioport.iop_pcdir |= 0x03c6; */ -/* immap->im_ioport.iop_pcpar &= ~0x03c6; */ - -/* cp->pio_pcdir |= 0x03c6; */ -/* cp->pio_pcpar &= ~0x03c6; */ - - - - /* Connect SCC2 and SCC3 to NMSI. Connect BRG3 to SCC2 and - * BRG4 to SCC3. - */ - cp->si_sicr &= ~0x00ffff00; - cp->si_sicr |= 0x001b1200; - -#ifdef CONFIG_PP04 - /* Frequentis PP04 forced to RS-232 until we know better. - * Port C 12 and 13 low enables RS-232 on SCC3 and SCC4. - */ - immap->im_ioport.iop_pcdir |= 0x000c; - immap->im_ioport.iop_pcpar &= ~0x000c; - immap->im_ioport.iop_pcdat &= ~0x000c; - - /* This enables the TX driver. - */ - cp->cp_pbpar &= ~0x6000; - cp->cp_pbdat &= ~0x6000; -#endif - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - printk(KERN_INFO "ttyS%d at irq 0x%02x is an %s\n", - i, (unsigned int)(state->irq), - (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC"); - -#ifdef CONFIG_SERIAL_CONSOLE - /* If we just printed the message on the console port, and - * we are about to initialize it for general use, we have - * to wait a couple of character times for the CR/NL to - * make it out of the transmit buffer. - */ - if (i == CONFIG_SERIAL_CONSOLE_PORT) - mdelay(8); - - -/* idx = PORT_NUM(info->state->smc_scc_num); */ -/* if (info->state->smc_scc_num & NUM_IS_SCC) */ -/* chan = scc_chan_map[idx]; */ -/* else */ -/* chan = smc_chan_map[idx]; */ - -/* cp->cp_cr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; */ -/* while (cp->cp_cr & CPM_CR_FLG); */ - -#endif - /* info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); */ - info = &quicc_ser_info[i]; - if (info) { - memset (info, 0, sizeof(ser_info_t)); - info->magic = SERIAL_MAGIC; - info->line = i; - info->flags = state->flags; - INIT_WORK(&info->tqueue, do_softint, info); - INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - info->state = state; - state->info = (struct async_struct *)info; - - /* We need to allocate a transmit and receive buffer - * descriptors from dual port ram, and a character - * buffer area from host mem. - */ - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * RX_NUM_FIFO); - - /* Allocate space for FIFOs in the host memory. - * (for now this is from a static array of buffers :( - */ - /* mem_addr = m360_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE); */ - /* mem_addr = kmalloc (RX_NUM_FIFO * RX_BUF_SIZE, GFP_BUFFER); */ - mem_addr = &rx_buf_pool[i * RX_NUM_FIFO * RX_BUF_SIZE]; - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - info->rx_cur = info->rx_bd_base = bdp; - - /* initialize rx buffer descriptors */ - for (j=0; j<(RX_NUM_FIFO-1); j++) { - bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE]; - bdp->status = BD_SC_EMPTY | BD_SC_INTRPT; - mem_addr += RX_BUF_SIZE; - bdp++; - } - bdp->buf = &rx_buf_pool[(i * RX_NUM_FIFO + j ) * RX_BUF_SIZE]; - bdp->status = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; - - - idx = PORT_NUM(info->state->smc_scc_num); - if (info->state->smc_scc_num & NUM_IS_SCC) { - -#if defined (CONFIG_UCQUICC) && 1 - /* set the transceiver mode to RS232 */ - sipex_mode_bits &= ~(uint)SIPEX_MODE(idx,0x0f); /* clear current mode */ - sipex_mode_bits |= (uint)SIPEX_MODE(idx,0x02); - *(uint *)_periph_base = sipex_mode_bits; - /* printk ("sipex bits = 0x%08x\n", sipex_mode_bits); */ -#endif - } - - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * TX_NUM_FIFO); - - /* Allocate space for FIFOs in the host memory. - */ - /* mem_addr = m360_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE); */ - /* mem_addr = kmalloc (TX_NUM_FIFO * TX_BUF_SIZE, GFP_BUFFER); */ - mem_addr = &tx_buf_pool[i * TX_NUM_FIFO * TX_BUF_SIZE]; - - /* Set the physical address of the host memory - * buffers in the buffer descriptors, and the - * virtual address for us to work with. - */ - /* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - info->tx_cur = info->tx_bd_base = (QUICC_BD *)bdp; - - /* initialize tx buffer descriptors */ - for (j=0; j<(TX_NUM_FIFO-1); j++) { - bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE]; - bdp->status = BD_SC_INTRPT; - mem_addr += TX_BUF_SIZE; - bdp++; - } - bdp->buf = &tx_buf_pool[(i * TX_NUM_FIFO + j ) * TX_BUF_SIZE]; - bdp->status = (BD_SC_WRAP | BD_SC_INTRPT); - - if (info->state->smc_scc_num & NUM_IS_SCC) { - scp = &pquicc->scc_regs[idx]; - sup = &pquicc->pram[info->state->port].scc.pscc.u; - sup->rbase = dp_addr; - sup->tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->rfcr = SMC_EB; - sup->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - sup->mrblr = 1; - sup->max_idl = 0; - sup->brkcr = 1; - sup->parec = 0; - sup->frmer = 0; - sup->nosec = 0; - sup->brkec = 0; - sup->uaddr1 = 0; - sup->uaddr2 = 0; - sup->toseq = 0; - { - int i; - for (i=0;i<8;i++) - sup->cc[i] = 0x8000; - } - sup->rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - chan = scc_chan_map[idx]; - - /* execute the INIT RX & TX PARAMS command for this channel. */ - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmr.w.high = 0; - scp->scc_gsmr.w.low = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_psmr = 0x3000; - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); -#endif - } - else { - /* Configure SMCs Tx/Rx instead of port B - * parallel I/O. - */ - up = &pquicc->pram[info->state->port].scc.pothers.idma_smc.psmc.u; - up->rbase = dp_addr; - - iobits = 0xc0 << (idx * 4); - cp->pip_pbpar |= iobits; - cp->pip_pbdir &= ~iobits; - cp->pip_pbodr &= ~iobits; - - - /* Connect the baud rate generator to the - * SMC based upon index in rs_table. Also - * make sure it is connected to NMSI. - */ - cp->si_simode &= ~(0xffff << (idx * 16)); - cp->si_simode |= (i << ((idx * 16) + 12)); - - up->tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - up->rfcr = SMC_EB; - up->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - up->mrblr = 1; - up->max_idl = 0; - up->brkcr = 1; - - /* Send the CPM an initialize command. - */ - chan = smc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, - CPM_CR_INIT_TRX) | CPM_CR_FLG; -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - printk(""); -#endif - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp = &cp->smc_regs[idx]; - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Disable all interrupts and clear all pending - * events. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -#endif - } - - /* Install interrupt handler. - */ - /* cpm_install_handler(IRQ_MACHSPEC | state->irq, rs_360_interrupt, info); */ - /*request_irq(IRQ_MACHSPEC | state->irq, rs_360_interrupt, */ - request_irq(state->irq, rs_360_interrupt, 0, "ttyS", - (void *)info); - - /* Set up the baud rate generator. - */ - m360_cpm_setbrg(i, baud_table[baud_idx]); - - } - } - - return 0; -} -module_init(rs_360_init); - -/* This must always be called before the rs_360_init() function, otherwise - * it blows away the port control information. - */ -//static int __init serial_console_setup( struct console *co, char *options) -int serial_console_setup( struct console *co, char *options) -{ - struct serial_state *ser; - uint mem_addr, dp_addr, bidx, idx, iobits; - ushort chan; - QUICC_BD *bdp; - volatile QUICC *cp; - volatile struct smc_regs *sp; - volatile struct scc_regs *scp; - volatile struct smc_uart_pram *up; - volatile struct uart_pram *sup; - -/* mleslie TODO: - * add something to the 68k bootloader to store a desired initial console baud rate */ - -/* bd_t *bd; */ /* a board info struct used by EPPC-bug */ -/* bd = (bd_t *)__res; */ - - for (bidx = 0; bidx < (sizeof(baud_table) / sizeof(int)); bidx++) - /* if (bd->bi_baudrate == baud_table[bidx]) */ - if (CONSOLE_BAUDRATE == baud_table[bidx]) - break; - - /* co->cflag = CREAD|CLOCAL|bidx|CS8; */ - baud_idx = bidx; - - ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; - - cp = pquicc; /* Get pointer to Communication Processor */ - - idx = PORT_NUM(ser->smc_scc_num); - if (ser->smc_scc_num & NUM_IS_SCC) { - - /* TODO: need to set up SCC pin assignment etc. here */ - - } - else { - iobits = 0xc0 << (idx * 4); - cp->pip_pbpar |= iobits; - cp->pip_pbdir &= ~iobits; - cp->pip_pbodr &= ~iobits; - - /* Connect the baud rate generator to the - * SMC based upon index in rs_table. Also - * make sure it is connected to NMSI. - */ - cp->si_simode &= ~(0xffff << (idx * 16)); - cp->si_simode |= (idx << ((idx * 16) + 12)); - } - - /* When we get here, the CPM has been reset, so we need - * to configure the port. - * We need to allocate a transmit and receive buffer descriptor - * from dual port ram, and a character buffer area from host mem. - */ - - /* Allocate space for two buffer descriptors in the DP ram. - */ - dp_addr = m360_cpm_dpalloc(sizeof(QUICC_BD) * CONSOLE_NUM_FIFO); - - /* Allocate space for two 2 byte FIFOs in the host memory. - */ - /* mem_addr = m360_cpm_hostalloc(8); */ - mem_addr = (uint)console_fifos; - - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - /* bdp = (QUICC_BD *)&cp->cp_dpmem[dp_addr]; */ - bdp = (QUICC_BD *)((uint)pquicc + dp_addr); - bdp->buf = (char *)mem_addr; - (bdp+1)->buf = (char *)(mem_addr+4); - - /* For the receive, set empty and wrap. - * For transmit, set wrap. - */ - bdp->status = BD_SC_EMPTY | BD_SC_WRAP; - (bdp+1)->status = BD_SC_WRAP; - - /* Set up the uart parameters in the parameter ram. - */ - if (ser->smc_scc_num & NUM_IS_SCC) { - scp = &cp->scc_regs[idx]; - /* sup = (scc_uart_t *)&cp->cp_dparam[ser->port]; */ - sup = &pquicc->pram[ser->port].scc.pscc.u; - - sup->rbase = dp_addr; - sup->tbase = dp_addr + sizeof(QUICC_BD); - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->rfcr = SMC_EB; - sup->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single - * character interrupts. Using idle character - * time requires some additional tuning. - */ - sup->mrblr = 1; - sup->max_idl = 0; - sup->brkcr = 1; - sup->parec = 0; - sup->frmer = 0; - sup->nosec = 0; - sup->brkec = 0; - sup->uaddr1 = 0; - sup->uaddr2 = 0; - sup->toseq = 0; - { - int i; - for (i=0;i<8;i++) - sup->cc[i] = 0x8000; - } - sup->rccm = 0xc0ff; - - /* Send the CPM an initialize command. - */ - chan = scc_chan_map[idx]; - - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - scp->scc_gsmr.w.high = 0; - scp->scc_gsmr.w.low = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); - - /* Disable all interrupts and clear all pending - * events. - */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_psmr = 0x3000; - - scp->scc_gsmr.w.low |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - } - else { - /* up = (smc_uart_t *)&cp->cp_dparam[ser->port]; */ - up = &pquicc->pram[ser->port].scc.pothers.idma_smc.psmc.u; - - up->rbase = dp_addr; /* Base of receive buffer desc. */ - up->tbase = dp_addr+sizeof(QUICC_BD); /* Base of xmt buffer desc. */ - up->rfcr = SMC_EB; - up->tfcr = SMC_EB; - - /* Set this to 1 for now, so we get single character interrupts. - */ - up->mrblr = 1; /* receive buffer length */ - up->max_idl = 0; /* wait forever for next char */ - - /* Send the CPM an initialize command. - */ - chan = smc_chan_map[idx]; - cp->cp_cr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp = &cp->smc_regs[idx]; - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* And finally, enable Rx and Tx. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; - } - - /* Set up the baud rate generator. - */ - /* m360_cpm_setbrg((ser - rs_table), bd->bi_baudrate); */ - m360_cpm_setbrg((ser - rs_table), CONSOLE_BAUDRATE); - - return 0; -} - -/* - * Local variables: - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ diff --git a/drivers/staging/serial/Kconfig b/drivers/staging/serial/Kconfig deleted file mode 100644 index 9489688..0000000 --- a/drivers/staging/serial/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config SERIAL_68360_SMC - bool "68360 SMC uart support" - depends on M68360 - help - This driver supports the SMC serial ports of the Motorola 68360 CPU. - -config SERIAL_68360_SCC - bool "68360 SCC uart support" - depends on M68360 - help - This driver supports the SCC serial ports of the Motorola 68360 CPU. - -config SERIAL_68360 - bool - depends on SERIAL_68360_SMC || SERIAL_68360_SCC - default y diff --git a/drivers/staging/serial/Makefile b/drivers/staging/serial/Makefile deleted file mode 100644 index 37a6a0b3..0000000 --- a/drivers/staging/serial/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SERIAL_68360) += 68360serial.o diff --git a/drivers/staging/serial/TODO b/drivers/staging/serial/TODO deleted file mode 100644 index a19cda8..0000000 --- a/drivers/staging/serial/TODO +++ /dev/null @@ -1,6 +0,0 @@ -These are a few serial drivers that either do not build, or do not work if they -do build, or if they seem to work, are for obsolete hardware, or are full of -unfixable races and no one uses them anymore. - -If no one steps up to adopt any of these drivers, they will be removed -in the 3.4 release. diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 83c582e..746c4cd5 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -2,31 +2,19 @@ * Silicon Motion SM7XX frame buffer device * * Copyright (C) 2006 Silicon Motion Technology Corp. - * Authors: Ge Wang, gewang@siliconmotion.com - * Boyod boyod.yang@siliconmotion.com.cn + * Authors: Ge Wang, gewang@siliconmotion.com + * Boyod boyod.yang@siliconmotion.com.cn * * Copyright (C) 2009 Lemote, Inc. - * Author: Wu Zhangjin, wuzhangjin@gmail.com + * Author: Wu Zhangjin, wuzhangjin@gmail.com * * Copyright (C) 2011 Igalia, S.L. - * Author: Javier M. Mellid <jmunhoz@igalia.com> + * Author: Javier M. Mellid <jmunhoz@igalia.com> * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. * - * Version 0.10.26192.21.01 - * - Add PowerPC/Big endian support - * - Verified on 2.6.19.2 - * Boyod.yang <boyod.yang@siliconmotion.com.cn> - * - * Version 0.09.2621.00.01 - * - Only support Linux Kernel's version 2.6.21 - * Boyod.yang <boyod.yang@siliconmotion.com.cn> - * - * Version 0.09 - * - Only support Linux Kernel's version 2.6.12 - * Boyod.yang <boyod.yang@siliconmotion.com.cn> */ #include <linux/io.h> @@ -45,40 +33,19 @@ #include "smtcfb.h" -#ifdef DEBUG -#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg) -#else -#define smdbg(format, arg...) -#endif - struct screen_info smtc_screen_info; /* * Private structure */ struct smtcfb_info { - /* - * The following is a pointer to be passed into the - * functions below. The modules outside the main - * voyager.c driver have no knowledge as to what - * is within this structure. - */ struct fb_info fb; - struct display_switch *dispsw; - struct pci_dev *dev; - signed int currcon; - + struct pci_dev *pdev; struct { u8 red, green, blue; } palette[NR_RGB]; - u_int palette_size; -}; -struct par_info { - /* - * Hardware - */ u16 chipID; unsigned char __iomem *m_pMMIO; char __iomem *m_pLFB; @@ -121,15 +88,6 @@ char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */ char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */ static u32 colreg[17]; -static struct par_info hw; /* hardware information */ - -u16 smtc_ChipIDs[] = { - 0x710, - 0x712, - 0x720 -}; - -#define numSMTCchipIDs ARRAY_SIZE(smtc_ChipIDs) static struct fb_var_screeninfo smtcfb_var = { .xres = 1024, @@ -154,30 +112,29 @@ static struct fb_fix_screeninfo smtcfb_fix = { .accel = FB_ACCEL_SMI_LYNX, }; -static void sm712_set_timing(struct smtcfb_info *sfb, - struct par_info *ppar_info) +static void sm712_set_timing(struct smtcfb_info *sfb) { int i = 0, j = 0; u32 m_nScreenStride; - smdbg("\nppar_info->width = %d ppar_info->height = %d" - "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n", - ppar_info->width, ppar_info->height, - sfb->fb.var.bits_per_pixel, ppar_info->hz); + dev_dbg(&sfb->pdev->dev, + "sfb->width=%d sfb->height=%d " + "sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n", + sfb->width, sfb->height, sfb->fb.var.bits_per_pixel, sfb->hz); for (j = 0; j < numVGAModes; j++) { - if (VGAMode[j].mmSizeX == ppar_info->width && - VGAMode[j].mmSizeY == ppar_info->height && + if (VGAMode[j].mmSizeX == sfb->width && + VGAMode[j].mmSizeY == sfb->height && VGAMode[j].bpp == sfb->fb.var.bits_per_pixel && - VGAMode[j].hz == ppar_info->hz) { + VGAMode[j].hz == sfb->hz) { - smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY =" - "%d VGAMode[j].bpp = %d" - "VGAMode[j].hz=%d\n", - VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, - VGAMode[j].bpp, VGAMode[j].hz); + dev_dbg(&sfb->pdev->dev, + "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d " + "VGAMode[j].bpp=%d VGAMode[j].hz=%d\n", + VGAMode[j].mmSizeX, VGAMode[j].mmSizeY, + VGAMode[j].bpp, VGAMode[j].hz); - smdbg("VGAMode index=%d\n", j); + dev_dbg(&sfb->pdev->dev, "VGAMode index=%d\n", j); smtc_mmiowb(0x0, 0x3c6); @@ -238,37 +195,37 @@ static void sm712_set_timing(struct smtcfb_info *sfb, smtc_mmiowb(0x67, 0x3c2); /* set VPR registers */ - writel(0x0, ppar_info->m_pVPR + 0x0C); - writel(0x0, ppar_info->m_pVPR + 0x40); + writel(0x0, sfb->m_pVPR + 0x0C); + writel(0x0, sfb->m_pVPR + 0x40); /* set data width */ m_nScreenStride = - (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64; + (sfb->width * sfb->fb.var.bits_per_pixel) / 64; switch (sfb->fb.var.bits_per_pixel) { case 8: - writel(0x0, ppar_info->m_pVPR + 0x0); + writel(0x0, sfb->m_pVPR + 0x0); break; case 16: - writel(0x00020000, ppar_info->m_pVPR + 0x0); + writel(0x00020000, sfb->m_pVPR + 0x0); break; case 24: - writel(0x00040000, ppar_info->m_pVPR + 0x0); + writel(0x00040000, sfb->m_pVPR + 0x0); break; case 32: - writel(0x00030000, ppar_info->m_pVPR + 0x0); + writel(0x00030000, sfb->m_pVPR + 0x0); break; } writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride), - ppar_info->m_pVPR + 0x10); + sfb->m_pVPR + 0x10); } static void sm712_setpalette(int regno, unsigned red, unsigned green, unsigned blue, struct fb_info *info) { - struct par_info *cur_par = (struct par_info *)info->par; + struct smtcfb_info *sfb = info->par; - if (cur_par->BaseAddressInVRAM) + if (sfb->BaseAddressInVRAM) /* * second display palette for dual head. Enable CRT RAM, 6-bit * RAM @@ -283,14 +240,13 @@ static void sm712_setpalette(int regno, unsigned red, unsigned green, smtc_mmiowb(blue >> 10, dac_val); } -static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info - *ppar_info) +static void smtc_set_timing(struct smtcfb_info *sfb) { - switch (ppar_info->chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: case 0x720: - sm712_set_timing(sfb, ppar_info); + sm712_set_timing(sfb); break; } } @@ -310,7 +266,7 @@ static inline unsigned int chan_to_field(unsigned int chan, return chan << bf->offset; } -static int cfb_blank(int blank_mode, struct fb_info *info) +static int smtc_blank(int blank_mode, struct fb_info *info) { /* clear DPMS setting */ switch (blank_mode) { @@ -660,10 +616,10 @@ void smtcfb_setmode(struct smtcfb_info *sfb) break; } - hw.width = sfb->fb.var.xres; - hw.height = sfb->fb.var.yres; - hw.hz = 60; - smtc_set_timing(sfb, &hw); + sfb->width = sfb->fb.var.xres; + sfb->height = sfb->fb.var.yres; + sfb->hz = 60; + smtc_set_timing(sfb); } static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info) @@ -697,7 +653,7 @@ static struct fb_ops smtcfb_ops = { .fb_check_var = smtc_check_var, .fb_set_par = smtc_set_par, .fb_setcolreg = smtc_setcolreg, - .fb_blank = cfb_blank, + .fb_blank = smtc_blank, .fb_fillrect = cfb_fillrect, .fb_imageblit = cfb_imageblit, .fb_copyarea = cfb_copyarea, @@ -710,8 +666,7 @@ static struct fb_ops smtcfb_ops = { /* * Alloc struct smtcfb_info and assign the default value */ -static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, - char *name) +static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev, char *name) { struct smtcfb_info *sfb; @@ -720,8 +675,7 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, if (!sfb) return NULL; - sfb->currcon = -1; - sfb->dev = dev; + sfb->pdev = pdev; /*** Init sfb->fb with default value ***/ sfb->fb.flags = FBINFO_FLAG_DEFAULT; @@ -745,7 +699,9 @@ static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev, /* text mode acceleration */ sfb->fb.var.accel_flags = FB_ACCELF_TEXT; sfb->fb.var.vmode = FB_VMODE_NONINTERLACED; - sfb->fb.par = &hw; + + sfb->fb.par = sfb; + sfb->fb.pseudo_palette = colreg; return sfb; @@ -766,17 +722,17 @@ static void smtc_unmap_mmio(struct smtcfb_info *sfb) */ static int smtc_map_smem(struct smtcfb_info *sfb, - struct pci_dev *dev, u_long smem_len) + struct pci_dev *pdev, u_long smem_len) { if (sfb->fb.var.bits_per_pixel == 32) { #ifdef __BIG_ENDIAN - sfb->fb.fix.smem_start = pci_resource_start(dev, 0) + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0) + 0x800000; #else - sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); #endif } else { - sfb->fb.fix.smem_start = pci_resource_start(dev, 0); + sfb->fb.fix.smem_start = pci_resource_start(pdev, 0); } sfb->fb.fix.smem_len = smem_len; @@ -784,8 +740,8 @@ static int smtc_map_smem(struct smtcfb_info *sfb, sfb->fb.screen_base = smtc_VRAMBaseAddress; if (!sfb->fb.screen_base) { - printk(KERN_ERR "%s: unable to map screen memory\n", - sfb->fb.fix.id); + dev_err(&pdev->dev, + "%s: unable to map screen memory\n", sfb->fb.fix.id); return -ENOMEM; } @@ -831,16 +787,14 @@ static int __init sm712vga_setup(char *options) { int index; - if (!options || !*options) { - smdbg("\n No vga parameter\n"); + if (!options || !*options) return -EINVAL; - } smtc_screen_info.lfb_width = 0; smtc_screen_info.lfb_height = 0; smtc_screen_info.lfb_depth = 0; - smdbg("\nsm712vga_setup = %s\n", options); + pr_debug("sm712vga_setup = %s\n", options); for (index = 0; index < ARRAY_SIZE(vesa_mode); @@ -858,10 +812,6 @@ static int __init sm712vga_setup(char *options) } __setup("vga=", sm712vga_setup); -/* Jason (08/13/2009) - * Original init function changed to probe method to be used by pci_drv - * process used to detect chips replaced with kernel process in pci_drv - */ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -871,23 +821,20 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, int err; unsigned long pFramebufferPhysical; - printk(KERN_INFO - "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n"); + dev_info(&pdev->dev, "Silicon Motion display driver."); err = pci_enable_device(pdev); /* enable SMTC chip */ if (err) return err; - hw.chipID = ent->device; - sprintf(name, "sm%Xfb", hw.chipID); - sfb = smtc_alloc_fb_info(pdev, name); if (!sfb) goto failed_free; - /* Jason (08/13/2009) - * Store fb_info to be further used when suspending and resuming - */ + + sfb->chipID = ent->device; + sprintf(name, "sm%Xfb", sfb->chipID); + pci_set_drvdata(pdev, sfb); sm7xx_init_hw(); @@ -910,37 +857,37 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, #endif /* Map address and memory detection */ pFramebufferPhysical = pci_resource_start(pdev, 0); - pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID); + pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chipRevID); - switch (hw.chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000; sfb->fb.fix.mmio_len = 0x00400000; smem_size = SM712_VIDEOMEMORYSIZE; #ifdef __BIG_ENDIAN - hw.m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pLFB = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00c00000)); #else - hw.m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pLFB = (smtc_VRAMBaseAddress = ioremap(pFramebufferPhysical, 0x00800000)); #endif - hw.m_pMMIO = (smtc_RegBaseAddress = + sfb->m_pMMIO = (smtc_RegBaseAddress = smtc_VRAMBaseAddress + 0x00700000); - hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000; - hw.m_pVPR = hw.m_pLFB + 0x0040c000; + sfb->m_pDPR = smtc_VRAMBaseAddress + 0x00408000; + sfb->m_pVPR = sfb->m_pLFB + 0x0040c000; #ifdef __BIG_ENDIAN if (sfb->fb.var.bits_per_pixel == 32) { smtc_VRAMBaseAddress += 0x800000; - hw.m_pLFB += 0x800000; - printk(KERN_INFO - "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n", - smtc_VRAMBaseAddress, hw.m_pLFB); + sfb->m_pLFB += 0x800000; + dev_info(&pdev->dev, + "smtc_VRAMBaseAddress=%p sfb->m_pLFB=%p", + smtc_VRAMBaseAddress, sfb->m_pLFB); } #endif if (!smtc_RegBaseAddress) { - printk(KERN_ERR - "%s: unable to map memory mapped IO\n", + dev_err(&pdev->dev, + "%s: unable to map memory mapped IO!", sfb->fb.fix.id); err = -ENOMEM; goto failed_fb; @@ -962,20 +909,20 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, sfb->fb.fix.mmio_start = pFramebufferPhysical; sfb->fb.fix.mmio_len = 0x00200000; smem_size = SM722_VIDEOMEMORYSIZE; - hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); - hw.m_pLFB = (smtc_VRAMBaseAddress = - hw.m_pDPR + 0x00200000); - hw.m_pMMIO = (smtc_RegBaseAddress = - hw.m_pDPR + 0x000c0000); - hw.m_pVPR = hw.m_pDPR + 0x800; + sfb->m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000); + sfb->m_pLFB = (smtc_VRAMBaseAddress = + sfb->m_pDPR + 0x00200000); + sfb->m_pMMIO = (smtc_RegBaseAddress = + sfb->m_pDPR + 0x000c0000); + sfb->m_pVPR = sfb->m_pDPR + 0x800; smtc_seqw(0x62, 0xff); smtc_seqw(0x6a, 0x0d); smtc_seqw(0x6b, 0x02); break; default: - printk(KERN_ERR - "No valid Silicon Motion display chip was detected!\n"); + dev_err(&pdev->dev, + "No valid Silicon Motion display chip was detected!"); goto failed_fb; } @@ -992,22 +939,21 @@ static int __devinit smtcfb_pci_probe(struct pci_dev *pdev, smtcfb_setmode(sfb); /* Primary display starting from 0 position */ - hw.BaseAddressInVRAM = 0; - sfb->fb.par = &hw; + sfb->BaseAddressInVRAM = 0; err = register_framebuffer(&sfb->fb); if (err < 0) goto failed; - printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode" - "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID, - sfb->fb.var.xres, sfb->fb.var.yres, - sfb->fb.var.bits_per_pixel); + dev_info(&pdev->dev, + "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.", + sfb->chipID, sfb->chipRevID, sfb->fb.var.xres, + sfb->fb.var.yres, sfb->fb.var.bits_per_pixel); return 0; failed: - printk(KERN_ERR "Silicon Motion, Inc. primary display init fail\n"); + dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail."); smtc_unmap_smem(sfb); smtc_unmap_mmio(sfb); @@ -1021,7 +967,6 @@ failed_free: } -/* Jason (08/11/2009) PCI_DRV wrapper essential structs */ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { { PCI_DEVICE(0x126f, 0x710), }, { PCI_DEVICE(0x126f, 0x712), }, @@ -1030,9 +975,6 @@ static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { }; -/* Jason (08/14/2009) - * do some clean up when the driver module is removed - */ static void __devexit smtcfb_pci_remove(struct pci_dev *pdev) { struct smtcfb_info *sfb; @@ -1078,7 +1020,7 @@ static int smtcfb_pci_resume(struct device *device) /* reinit hardware */ sm7xx_init_hw(); - switch (hw.chipID) { + switch (sfb->chipID) { case 0x710: case 0x712: /* set MCLK = 14.31818 * (0x16 / 0x2) */ diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h index ab95af2..43d86f8 100644 --- a/drivers/staging/sm7xx/smtcfb.h +++ b/drivers/staging/sm7xx/smtcfb.h @@ -13,19 +13,11 @@ * more details. */ -#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008" - #define NR_PALETTE 256 #define NR_RGB 2 #define FB_ACCEL_SMI_LYNX 88 -#ifdef __BIG_ENDIAN -#define PC_VGA 0 -#else -#define PC_VGA 1 -#endif - #define SCREEN_X_RES 1024 #define SCREEN_Y_RES 600 #define SCREEN_BPP 16 diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c index f960279..fd7757a 100644 --- a/drivers/staging/telephony/ixj.c +++ b/drivers/staging/telephony/ixj.c @@ -19,20 +19,20 @@ * David W. Erhart, <derhart@quicknet.net> * John Sellers, <jsellers@quicknet.net> * Mike Preston, <mpreston@quicknet.net> - * + * * Fixes: David Huggins-Daines, <dhd@cepstral.com> * Fabio Ferrari, <fabio.ferrari@digitro.com.br> * Artis Kugevics, <artis@mt.lv> * Daniele Bellucci, <bellucda@tiscali.it> * - * More information about the hardware related to this driver can be found + * More information about the hardware related to this driver can be found * at our website: http://www.quicknet.net * * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS @@ -317,7 +317,7 @@ static IXJ *ixj[IXJMAX]; /* * Allocate a free IXJ device */ - + static IXJ *ixj_alloc() { for(cnt=0; cnt<IXJMAX; cnt++) @@ -366,7 +366,7 @@ static IXJ ixj[IXJMAX]; /* * Allocate a free IXJ device */ - + static IXJ *ixj_alloc(void) { int cnt; @@ -1084,7 +1084,7 @@ static void ixj_pstn_state(IXJ *j) printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max); break; - case 6: + case 6: printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max); break; @@ -1109,7 +1109,7 @@ static void ixj_pstn_state(IXJ *j) } j->pstn_ring_stop = j->pstn_ring_int = 0; daa_set_mode(j, SOP_PU_SLEEP); - } + } outb_p(j->pld_scrw.byte, j->XILINXbase); if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) { ixj_daa_cid_read(j); @@ -1133,7 +1133,7 @@ static void ixj_pstn_state(IXJ *j) printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies); } j->pstn_winkstart = jiffies; - } + } } else { if (j->pstn_winkstart) { if(ixjdebug & 0x0008) { @@ -1524,7 +1524,7 @@ static inline void LED_SetState(int state, IXJ *j) /********************************************************************* * GPIO Pins are configured as follows on the Quicknet Internet * PhoneJACK Telephony Cards -* +* * POTS Select GPIO_6=0 GPIO_7=0 * Mic/Speaker Select GPIO_6=0 GPIO_7=1 * Handset Select GPIO_6=1 GPIO_7=0 @@ -1932,7 +1932,7 @@ static int ixj_hookstate(IXJ *j) if(fOffHook != j->p_hook) { if(!j->checkwait) { j->checkwait = jiffies; - } + } if(time_before(jiffies, j->checkwait + 2)) { fOffHook ^= 1; } else { @@ -2342,8 +2342,8 @@ static int ixj_release(struct inode *inode, struct file *file_p) j->ixj_signals[cnt] = SIGIO; /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; file_p->private_data = NULL; @@ -2506,7 +2506,7 @@ static int read_filters(IXJ *j) j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max); break; case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, + printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, j->cadence_f[cnt].off1max); break; case 3: @@ -2521,12 +2521,12 @@ static int read_filters(IXJ *j) printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min, j->cadence_f[cnt].on3max); break; - case 6: + case 6: printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min, j->cadence_f[cnt].off3max); break; } - } + } } if (j->cadence_f[cnt].state == 7) { j->cadence_f[cnt].state = 0; @@ -2656,37 +2656,37 @@ static void ulaw2alaw(unsigned char *buff, unsigned long len) { static unsigned char table_ulaw2alaw[] = { - 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, - 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, - 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, - 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, - 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, - 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, - 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, - 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, - 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, - 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, - 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, - 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, - 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, - 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, - 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, - 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, - 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, - 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, - 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, - 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, - 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, - 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, - 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, - 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, - 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, - 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, - 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, - 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, - 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, - 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, - 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, + 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, + 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, + 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, + 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, + 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, + 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, + 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, + 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, + 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, + 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, + 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, + 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, + 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, + 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, + 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, + 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, + 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, + 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, + 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, + 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, + 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, + 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, + 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, + 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, + 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, + 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, + 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, + 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, + 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, + 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, + 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5 }; @@ -2701,37 +2701,37 @@ static void alaw2ulaw(unsigned char *buff, unsigned long len) { static unsigned char table_alaw2ulaw[] = { - 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, - 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, - 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, - 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, - 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, - 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, - 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, - 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, - 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, - 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, - 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, - 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, - 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, - 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, - 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, - 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, - 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, - 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, - 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, - 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, - 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, - 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, - 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, - 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, - 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, - 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, - 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, - 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, - 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, + 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, + 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, + 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, + 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, + 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, + 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, + 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, + 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, + 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, + 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, + 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, + 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, + 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, + 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, + 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, + 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, + 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, + 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, + 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, + 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, + 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, + 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, + 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, + 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, + 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, + 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, + 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, + 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, + 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, + 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, + 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1 }; @@ -3090,7 +3090,7 @@ static int ixj_write_cid_string(IXJ *j, char *s, int checksum) static void ixj_pad_fsk(IXJ *j, int pad) { - int cnt; + int cnt; for (cnt = 0; cnt < pad; cnt++) { if(j->fskdcnt < (j->fsksize - 1)) @@ -3474,7 +3474,7 @@ static void ixj_write_frame(IXJ *j) ixj_post_cid(j); } /* This may seem rude, but if we just played one frame of FSK data for CallerID - and there is real audio data in the buffer, we need to throw it away because + and there is real audio data in the buffer, we need to throw it away because we just used it's time slot */ if (j->write_buffer_rp > j->write_buffer_wp) { j->write_buffer_rp += j->cid_play_frame_size * 2; @@ -3486,7 +3486,7 @@ static void ixj_write_frame(IXJ *j) wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ } - } else if (j->write_buffer && j->write_buffers_empty < 1) { + } else if (j->write_buffer && j->write_buffers_empty < 1) { if (j->write_buffer_wp > j->write_buffer_rp) { frame_count = (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); @@ -4150,7 +4150,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_MED: @@ -4161,7 +4161,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_HIGH: @@ -4172,7 +4172,7 @@ static void ixj_aec_start(IXJ *j, int level) ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0000, j); /* to off */ - + break; case AEC_AGC: @@ -4197,28 +4197,28 @@ static void ixj_aec_start(IXJ *j, int level) /* Now we can set the AGC initial parameters and turn it on */ ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ - + ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */ - + ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */ ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */ - + ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */ ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */ - + ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */ ixj_WriteDSPCommand(0x0005, j); /* to 8ms */ - + ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */ ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */ - + ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */ ixj_WriteDSPCommand(0x1200, j); /* to 25% */ - + ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ ixj_WriteDSPCommand(0x0001, j); /* to on */ - + break; case AEC_AUTO: @@ -4495,7 +4495,7 @@ static int ixj_play_start(IXJ *j) return -ENOMEM; } /* j->write_buffers_empty = 2; */ - j->write_buffers_empty = 1; + j->write_buffers_empty = 1; j->write_buffer_size = j->play_frame_size * 2; j->write_buffer_end = j->write_buffer + j->play_frame_size * 2; j->write_buffer_rp = j->write_buffer_wp = j->write_buffer; @@ -6465,9 +6465,9 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar ixj_ringback(j); break; case PHONE_WINK: - if(j->cardtype == QTI_PHONEJACK) + if(j->cardtype == QTI_PHONEJACK) retval = -1; - else + else retval = ixj_wink(j); break; case PHONE_CPT_STOP: @@ -6553,7 +6553,7 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar ixj_write_vmwi(j, arg); break; case IXJCTL_CID: - if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) + if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) retval = -EFAULT; j->ex.bits.caller_id = 0; break; @@ -6575,13 +6575,13 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar break; case PHONE_CAPABILITIES_LIST: add_caps(j); - if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) + if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) retval = -EFAULT; break; case PHONE_CAPABILITIES_CHECK: { struct phone_capability cap; - if (copy_from_user(&cap, argp, sizeof(cap))) + if (copy_from_user(&cap, argp, sizeof(cap))) retval = -EFAULT; else { add_caps(j); @@ -6597,13 +6597,13 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar j->ex.bits.pstn_ring = 0; break; case IXJCTL_SET_FILTER: - if (copy_from_user(&jf, argp, sizeof(jf))) + if (copy_from_user(&jf, argp, sizeof(jf))) retval = -EFAULT; else retval = ixj_init_filter(j, &jf); break; case IXJCTL_SET_FILTER_RAW: - if (copy_from_user(&jfr, argp, sizeof(jfr))) + if (copy_from_user(&jfr, argp, sizeof(jfr))) retval = -EFAULT; else retval = ixj_init_filter_raw(j, &jfr); @@ -6638,9 +6638,9 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar raise *= 2; } if(j->sigdef.signal) - j->ex_sig.bytes |= raise; + j->ex_sig.bytes |= raise; else - j->ex_sig.bytes &= (raise^0xffff); + j->ex_sig.bytes &= (raise^0xffff); } break; case IXJCTL_INTERCOM_STOP: @@ -7040,9 +7040,9 @@ static int ixj_selfprobe(IXJ *j) /* initialise the DTMF prescale to a sensible value */ if (j->cardtype == QTI_LINEJACK) { - set_dtmf_prescale(j, 0x10); + set_dtmf_prescale(j, 0x10); } else { - set_dtmf_prescale(j, 0x40); + set_dtmf_prescale(j, 0x40); } set_play_volume(j, 0x100); set_rec_volume(j, 0x100); @@ -7095,15 +7095,15 @@ static int ixj_selfprobe(IXJ *j) j->ixj_signals[cnt] = SIGIO; /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = + j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = + j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; #ifdef IXJ_DYN_ALLOC j->fskdata = NULL; #endif j->fskdcnt = 0; j->cidcw_wait = 0; - + /* Register with the Telephony for Linux subsystem */ j->p.f_op = &ixj_fops; j->p.open = ixj_open; @@ -7118,7 +7118,7 @@ static int ixj_selfprobe(IXJ *j) /* * Exported service for pcmcia card handling */ - + IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx) { IXJ *j = ixj_alloc(); @@ -7320,7 +7320,7 @@ static int ixj_get_status_proc(char *buf) len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j)); len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j)); len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j)); - + len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */ if (j->cardtype == QTI_LINEJACK) { @@ -7417,7 +7417,7 @@ static int ixj_get_status_proc(char *buf) len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail); len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready); len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail); - + #endif len += sprintf(buf + len, "\n"); } @@ -7608,7 +7608,7 @@ static IXJ *new_ixj(unsigned long port) } static int __init ixj_probe_isapnp(int *cnt) -{ +{ int probe = 0; int func = 0x110; struct pnp_dev *dev = NULL, *old_dev = NULL; @@ -7686,7 +7686,7 @@ static int __init ixj_probe_isapnp(int *cnt) } return probe; } - + static int __init ixj_probe_isa(int *cnt) { int i, probe; @@ -7713,7 +7713,7 @@ static int __init ixj_probe_isa(int *cnt) static int __init ixj_probe_pci(int *cnt) { - struct pci_dev *pci = NULL; + struct pci_dev *pci = NULL; int i, probe = 0; IXJ *j = NULL; @@ -7745,7 +7745,7 @@ static int __init ixj_probe_pci(int *cnt) static int __init ixj_init(void) { int cnt = 0; - int probe = 0; + int probe = 0; cnt = 0; @@ -7887,7 +7887,7 @@ static void DAA_Coeff_US(IXJ *j) /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */ - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ + /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */ /* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */ diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c index 9b50b5b..c51f651 100644 --- a/drivers/staging/tidspbridge/core/io_sm.c +++ b/drivers/staging/tidspbridge/core/io_sm.c @@ -2212,7 +2212,7 @@ void dump_dl_modules(struct bridge_dev_context *bridge_context) if (status) { pr_debug( - "%s: Failed to read dll_module stuct for 0x%x.\n", + "%s: Failed to read dll_module struct for 0x%x.\n", __func__, module_dsp_addr); break; } diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 006ffd7..3d28b23 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -215,7 +215,7 @@ static inline const char *event_to_string(int event) case DSP_MMUFAULT: return "DSP_MMUFAULT"; break; case DSP_PWRERROR: return "DSP_PWRERROR"; break; case DSP_WDTOVERFLOW: return "DSP_WDTOVERFLOW"; break; - default: return "unkown event"; break; + default: return "unknown event"; break; } } diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index fa870e3..92ced35 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -113,8 +113,8 @@ static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, spin_unlock(&sdev->ud.lock); - sdev->ud.tcp_rx = kthread_run(stub_rx_loop, &sdev->ud, "stub_rx"); - sdev->ud.tcp_tx = kthread_run(stub_tx_loop, &sdev->ud, "stub_tx"); + sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, "stub_rx"); + sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, "stub_tx"); spin_lock(&sdev->ud.lock); sdev->ud.status = SDEV_ST_USED; @@ -187,10 +187,10 @@ static void stub_shutdown_connection(struct usbip_device *ud) } /* 1. stop threads */ - if (ud->tcp_rx && !task_is_dead(ud->tcp_rx)) - kthread_stop(ud->tcp_rx); - if (ud->tcp_tx && !task_is_dead(ud->tcp_tx)) - kthread_stop(ud->tcp_tx); + if (ud->tcp_rx) + kthread_stop_put(ud->tcp_rx); + if (ud->tcp_tx) + kthread_stop_put(ud->tcp_tx); /* * 2. close the socket diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index c7b888c..5d89c0f 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -292,6 +292,23 @@ struct usbip_device { } eh_ops; }; +#define kthread_get_run(threadfn, data, namefmt, ...) \ +({ \ + struct task_struct *__k \ + = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \ + if (!IS_ERR(__k)) { \ + get_task_struct(__k); \ + wake_up_process(__k); \ + } \ + __k; \ +}) + +#define kthread_stop_put(k) \ + do { \ + kthread_stop(k); \ + put_task_struct(k); \ + } while (0) + /* usbip_common.c */ void usbip_dump_urb(struct urb *purb); void usbip_dump_header(struct usbip_header *pdu); diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/staging/usbip/usbip_protocol.txt index 0f10208..16b6fe2 100644 --- a/drivers/staging/usbip/usbip_protocol.txt +++ b/drivers/staging/usbip/usbip_protocol.txt @@ -27,7 +27,7 @@ Once the client knows the list of exported USB devices it may decide to use one of them. First the client opens a TCP/IP connection towards the server and sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the import was successful the TCP/IP connection remains open and will be used -to trasfer the URB traffic between the client and the server. The client may +to transfer the URB traffic between the client and the server. The client may send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index 2697877..0958ba5 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -59,7 +59,10 @@ static int parse_status(char *value) /* skip a header line */ - c = strchr(value, '\n') + 1; + c = strchr(value, '\n'); + if (!c) + return -1; + c++; while (*c != '\0') { int port, status, speed, devid; @@ -109,7 +112,10 @@ static int parse_status(char *value) /* go to the next line */ - c = strchr(c, '\n') + 1; + c = strchr(c, '\n'); + if (!c) + break; + c++; } dbg("exit"); @@ -264,11 +270,17 @@ static int get_nports(void) attr_status->method, attr_status->value); /* skip a header line */ - c = strchr(attr_status->value, '\n') + 1; + c = strchr(attr_status->value, '\n'); + if (!c) + return 0; + c++; while (*c != '\0') { /* go to the next line */ - c = strchr(c, '\n') + 1; + c = strchr(c, '\n'); + if (!c) + return nports; + c++; nports += 1; } diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index dca9bf1..f708cba 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -821,10 +821,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) - kthread_stop(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx)) - kthread_stop(vdev->ud.tcp_tx); + if (vdev->ud.tcp_rx) + kthread_stop_put(vdev->ud.tcp_rx); + if (vdev->ud.tcp_tx) + kthread_stop_put(vdev->ud.tcp_tx); pr_info("stop threads\n"); diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index f5fba732..f0eaf04f 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -162,7 +162,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, * already received the result of its submit result and gave * back the URB. */ - pr_info("the urb (seqnum %d) was already given backed\n", + pr_info("the urb (seqnum %d) was already given back\n", pdu->base.seqnum); } else { usbip_dbg_vhci_rx("now giveback urb %p\n", urb); diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 0cd039b..7ce9c2f 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -222,8 +222,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, spin_unlock(&the_controller->lock); /* end the lock */ - vdev->ud.tcp_rx = kthread_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); - vdev->ud.tcp_tx = kthread_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); + vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); + vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); rh_port_connect(rhport, speed); diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig deleted file mode 100644 index 6411ae5..0000000 --- a/drivers/staging/vme/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# -# VME configuration. -# - -menuconfig VME_BUS - tristate "VME bridge support" - depends on PCI - ---help--- - If you say Y here you get support for the VME bridge Framework. - -if VME_BUS - -source "drivers/staging/vme/bridges/Kconfig" - -source "drivers/staging/vme/devices/Kconfig" - -source "drivers/staging/vme/boards/Kconfig" - -endif # VME diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile index b4ea3f8..accdb72 100644 --- a/drivers/staging/vme/Makefile +++ b/drivers/staging/vme/Makefile @@ -1,8 +1 @@ -# -# Makefile for the VME bridge device drivers. -# -obj-$(CONFIG_VME_BUS) += vme.o - -obj-y += bridges/ obj-y += devices/ -obj-y += boards/ diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO deleted file mode 100644 index 79f0033..0000000 --- a/drivers/staging/vme/TODO +++ /dev/null @@ -1,5 +0,0 @@ - TODO - ==== - -- Add one or more device drivers which use the VME framework. - diff --git a/drivers/staging/vme/boards/Kconfig b/drivers/staging/vme/boards/Kconfig deleted file mode 100644 index 7616313..0000000 --- a/drivers/staging/vme/boards/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -comment "VME Board Drivers" - -config VMIVME_7805 - tristate "VMIVME-7805" - help - If you say Y here you get support for the VMIVME-7805 board. - This board has an additional control interface to the Universe II - chip. This driver has to be included if you want to access VME bus - with VMIVME-7805 board. diff --git a/drivers/staging/vme/boards/Makefile b/drivers/staging/vme/boards/Makefile deleted file mode 100644 index 4365834..0000000 --- a/drivers/staging/vme/boards/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the VME board drivers. -# - -obj-$(CONFIG_VMIVME_7805) += vme_vmivme7805.o diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c deleted file mode 100644 index 8e05bb4..0000000 --- a/drivers/staging/vme/boards/vme_vmivme7805.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Support for the VMIVME-7805 board access to the Universe II bridge. - * - * Author: Arthur Benilov <arthur.benilov@iba-group.com> - * Copyright 2010 Ion Beam Application, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/poll.h> -#include <linux/io.h> - -#include "vme_vmivme7805.h" - -static int __init vmic_init(void); -static int vmic_probe(struct pci_dev *, const struct pci_device_id *); -static void vmic_remove(struct pci_dev *); -static void __exit vmic_exit(void); - -/** Base address to access FPGA register */ -static void *vmic_base; - -static const char driver_name[] = "vmivme_7805"; - -static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, - { }, -}; - -static struct pci_driver vmic_driver = { - .name = driver_name, - .id_table = vmic_ids, - .probe = vmic_probe, - .remove = vmic_remove, -}; - -static int __init vmic_init(void) -{ - return pci_register_driver(&vmic_driver); -} - -static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval; - u32 data; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* Map registers in BAR 0 */ - vmic_base = ioremap_nocache(pci_resource_start(pdev, 0), 16); - if (!vmic_base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Clear the FPGA VME IF contents */ - iowrite32(0, vmic_base + VME_CONTROL); - - /* Clear any initial BERR */ - data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; - data |= BM_VME_CONTROL_BERRST; - iowrite32(data, vmic_base + VME_CONTROL); - - /* Enable the vme interface and byte swapping */ - data = ioread32(vmic_base + VME_CONTROL) & 0x00000FFF; - data = data | BM_VME_CONTROL_MASTER_ENDIAN | - BM_VME_CONTROL_SLAVE_ENDIAN | - BM_VME_CONTROL_ABLE | - BM_VME_CONTROL_BERRI | - BM_VME_CONTROL_BPENA | - BM_VME_CONTROL_VBENA; - iowrite32(data, vmic_base + VME_CONTROL); - - return 0; - -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err: - return retval; -} - -static void vmic_remove(struct pci_dev *pdev) -{ - iounmap(vmic_base); - pci_release_regions(pdev); - pci_disable_device(pdev); - -} - -static void __exit vmic_exit(void) -{ - pci_unregister_driver(&vmic_driver); -} - -MODULE_DESCRIPTION("VMIVME-7805 board support driver"); -MODULE_AUTHOR("Arthur Benilov <arthur.benilov@iba-group.com>"); -MODULE_LICENSE("GPL"); - -module_init(vmic_init); -module_exit(vmic_exit); - diff --git a/drivers/staging/vme/boards/vme_vmivme7805.h b/drivers/staging/vme/boards/vme_vmivme7805.h deleted file mode 100644 index 44c2c44..0000000 --- a/drivers/staging/vme/boards/vme_vmivme7805.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * vmivme_7805.h - * - * Support for the VMIVME-7805 board access to the Universe II bridge. - * - * Author: Arthur Benilov <arthur.benilov@iba-group.com> - * Copyright 2010 Ion Beam Application, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - - -#ifndef _VMIVME_7805_H -#define _VMIVME_7805_H - -#ifndef PCI_VENDOR_ID_VMIC -#define PCI_VENDOR_ID_VMIC 0x114A -#endif - -#ifndef PCI_DEVICE_ID_VTIMR -#define PCI_DEVICE_ID_VTIMR 0x0004 -#endif - -#define VME_CONTROL 0x0000 -#define BM_VME_CONTROL_MASTER_ENDIAN 0x0001 -#define BM_VME_CONTROL_SLAVE_ENDIAN 0x0002 -#define BM_VME_CONTROL_ABLE 0x0004 -#define BM_VME_CONTROL_BERRI 0x0040 -#define BM_VME_CONTROL_BERRST 0x0080 -#define BM_VME_CONTROL_BPENA 0x0400 -#define BM_VME_CONTROL_VBENA 0x0800 - -#endif /* _VMIVME_7805_H */ - diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig deleted file mode 100644 index 9331064..0000000 --- a/drivers/staging/vme/bridges/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -comment "VME Bridge Drivers" - -config VME_CA91CX42 - tristate "Universe II" - depends on VIRT_TO_BUS - help - If you say Y here you get support for the Tundra CA91C142 - (Universe II) VME bridge chip. - -config VME_TSI148 - tristate "Tempe" - depends on VIRT_TO_BUS - help - If you say Y here you get support for the Tundra TSI148 VME bridge - chip. diff --git a/drivers/staging/vme/bridges/Makefile b/drivers/staging/vme/bridges/Makefile deleted file mode 100644 index 59638af..0000000 --- a/drivers/staging/vme/bridges/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_VME_CA91CX42) += vme_ca91cx42.o -obj-$(CONFIG_VME_TSI148) += vme_tsi148.o diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c deleted file mode 100644 index 515b8b8..0000000 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* - * Support for the Tundra Universe I/II VME-PCI Bridge Chips - * - * Author: Martyn Welch <martyn.welch@ge.com> - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola Inc. - * - * Derived from ca91c042.c by Michael Wyrick - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> -#include <linux/poll.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/time.h> -#include <linux/io.h> -#include <linux/uaccess.h> - -#include "../vme.h" -#include "../vme_bridge.h" -#include "vme_ca91cx42.h" - -static int __init ca91cx42_init(void); -static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); -static void ca91cx42_remove(struct pci_dev *); -static void __exit ca91cx42_exit(void); - -/* Module parameters */ -static int geoid; - -static const char driver_name[] = "vme_ca91cx42"; - -static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, - { }, -}; - -static struct pci_driver ca91cx42_driver = { - .name = driver_name, - .id_table = ca91cx42_ids, - .probe = ca91cx42_probe, - .remove = ca91cx42_remove, -}; - -static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge) -{ - wake_up(&bridge->dma_queue); - - return CA91CX42_LINT_DMA; -} - -static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat) -{ - int i; - u32 serviced = 0; - - for (i = 0; i < 4; i++) { - if (stat & CA91CX42_LINT_LM[i]) { - /* We only enable interrupts if the callback is set */ - bridge->lm_callback[i](i); - serviced |= CA91CX42_LINT_LM[i]; - } - } - - return serviced; -} - -/* XXX This needs to be split into 4 queues */ -static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask) -{ - wake_up(&bridge->mbox_queue); - - return CA91CX42_LINT_MBOX; -} - -static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) -{ - wake_up(&bridge->iack_queue); - - return CA91CX42_LINT_SW_IACK; -} - -static u32 ca91cx42_VERR_irqhandler(struct vme_bridge *ca91cx42_bridge) -{ - int val; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - val = ioread32(bridge->base + DGCS); - - if (!(val & 0x00000800)) { - dev_err(ca91cx42_bridge->parent, "ca91cx42_VERR_irqhandler DMA " - "Read Error DGCS=%08X\n", val); - } - - return CA91CX42_LINT_VERR; -} - -static u32 ca91cx42_LERR_irqhandler(struct vme_bridge *ca91cx42_bridge) -{ - int val; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - val = ioread32(bridge->base + DGCS); - - if (!(val & 0x00000800)) - dev_err(ca91cx42_bridge->parent, "ca91cx42_LERR_irqhandler DMA " - "Read Error DGCS=%08X\n", val); - - return CA91CX42_LINT_LERR; -} - - -static u32 ca91cx42_VIRQ_irqhandler(struct vme_bridge *ca91cx42_bridge, - int stat) -{ - int vec, i, serviced = 0; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - - for (i = 7; i > 0; i--) { - if (stat & (1 << i)) { - vec = ioread32(bridge->base + - CA91CX42_V_STATID[i]) & 0xff; - - vme_irq_handler(ca91cx42_bridge, i, vec); - - serviced |= (1 << i); - } - } - - return serviced; -} - -static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) -{ - u32 stat, enable, serviced = 0; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = ptr; - - bridge = ca91cx42_bridge->driver_priv; - - enable = ioread32(bridge->base + LINT_EN); - stat = ioread32(bridge->base + LINT_STAT); - - /* Only look at unmasked interrupts */ - stat &= enable; - - if (unlikely(!stat)) - return IRQ_NONE; - - if (stat & CA91CX42_LINT_DMA) - serviced |= ca91cx42_DMA_irqhandler(bridge); - if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | - CA91CX42_LINT_LM3)) - serviced |= ca91cx42_LM_irqhandler(bridge, stat); - if (stat & CA91CX42_LINT_MBOX) - serviced |= ca91cx42_MB_irqhandler(bridge, stat); - if (stat & CA91CX42_LINT_SW_IACK) - serviced |= ca91cx42_IACK_irqhandler(bridge); - if (stat & CA91CX42_LINT_VERR) - serviced |= ca91cx42_VERR_irqhandler(ca91cx42_bridge); - if (stat & CA91CX42_LINT_LERR) - serviced |= ca91cx42_LERR_irqhandler(ca91cx42_bridge); - if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 | - CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 | - CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 | - CA91CX42_LINT_VIRQ7)) - serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); - - /* Clear serviced interrupts */ - iowrite32(serviced, bridge->base + LINT_STAT); - - return IRQ_HANDLED; -} - -static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge) -{ - int result, tmp; - struct pci_dev *pdev; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Need pdev */ - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); - - /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&ca91cx42_bridge->vme_errors); - - mutex_init(&ca91cx42_bridge->irq_mtx); - - /* Disable interrupts from PCI to VME */ - iowrite32(0, bridge->base + VINT_EN); - - /* Disable PCI interrupts */ - iowrite32(0, bridge->base + LINT_EN); - /* Clear Any Pending PCI Interrupts */ - iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); - - result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED, - driver_name, ca91cx42_bridge); - if (result) { - dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n", - pdev->irq); - return result; - } - - /* Ensure all interrupts are mapped to PCI Interrupt 0 */ - iowrite32(0, bridge->base + LINT_MAP0); - iowrite32(0, bridge->base + LINT_MAP1); - iowrite32(0, bridge->base + LINT_MAP2); - - /* Enable DMA, mailbox & LM Interrupts */ - tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 | - CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK | - CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA; - - iowrite32(tmp, bridge->base + LINT_EN); - - return 0; -} - -static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, - struct pci_dev *pdev) -{ - /* Disable interrupts from PCI to VME */ - iowrite32(0, bridge->base + VINT_EN); - - /* Disable PCI interrupts */ - iowrite32(0, bridge->base + LINT_EN); - /* Clear Any Pending PCI Interrupts */ - iowrite32(0x00FFFFFF, bridge->base + LINT_STAT); - - free_irq(pdev->irq, pdev); -} - -static int ca91cx42_iack_received(struct ca91cx42_driver *bridge, int level) -{ - u32 tmp; - - tmp = ioread32(bridge->base + LINT_STAT); - - if (tmp & (1 << level)) - return 0; - else - return 1; -} - -/* - * Set up an VME interrupt - */ -static void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, - int state, int sync) - -{ - struct pci_dev *pdev; - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Enable IRQ level */ - tmp = ioread32(bridge->base + LINT_EN); - - if (state == 0) - tmp &= ~CA91CX42_LINT_VIRQ[level]; - else - tmp |= CA91CX42_LINT_VIRQ[level]; - - iowrite32(tmp, bridge->base + LINT_EN); - - if ((state == 0) && (sync != 0)) { - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, - dev); - - synchronize_irq(pdev->irq); - } -} - -static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, - int statid) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Universe can only generate even vectors */ - if (statid & 1) - return -EINVAL; - - mutex_lock(&bridge->vme_int); - - tmp = ioread32(bridge->base + VINT_EN); - - /* Set Status/ID */ - iowrite32(statid << 24, bridge->base + STATID); - - /* Assert VMEbus IRQ */ - tmp = tmp | (1 << (level + 24)); - iowrite32(tmp, bridge->base + VINT_EN); - - /* Wait for IACK */ - wait_event_interruptible(bridge->iack_queue, - ca91cx42_iack_received(bridge, level)); - - /* Return interrupt to low state */ - tmp = ioread32(bridge->base + VINT_EN); - tmp = tmp & ~(1 << (level + 24)); - iowrite32(tmp, bridge->base + VINT_EN); - - mutex_unlock(&bridge->vme_int); - - return 0; -} - -static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t pci_base, u32 aspace, u32 cycle) -{ - unsigned int i, addr = 0, granularity; - unsigned int temp_ctl = 0; - unsigned int vme_bound, pci_offset; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = image->parent; - - bridge = ca91cx42_bridge->driver_priv; - - i = image->number; - - switch (aspace) { - case VME_A16: - addr |= CA91CX42_VSI_CTL_VAS_A16; - break; - case VME_A24: - addr |= CA91CX42_VSI_CTL_VAS_A24; - break; - case VME_A32: - addr |= CA91CX42_VSI_CTL_VAS_A32; - break; - case VME_USER1: - addr |= CA91CX42_VSI_CTL_VAS_USER1; - break; - case VME_USER2: - addr |= CA91CX42_VSI_CTL_VAS_USER2; - break; - case VME_A64: - case VME_CRCSR: - case VME_USER3: - case VME_USER4: - default: - dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - /* - * Bound address is a valid address for the window, adjust - * accordingly - */ - vme_bound = vme_base + size; - pci_offset = pci_base - vme_base; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - if (vme_base & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME base " - "alignment\n"); - return -EINVAL; - } - if (vme_bound & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME bound " - "alignment\n"); - return -EINVAL; - } - if (pci_offset & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid PCI Offset " - "alignment\n"); - return -EINVAL; - } - - /* Disable while we are mucking around */ - temp_ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); - temp_ctl &= ~CA91CX42_VSI_CTL_EN; - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - /* Setup mapping */ - iowrite32(vme_base, bridge->base + CA91CX42_VSI_BS[i]); - iowrite32(vme_bound, bridge->base + CA91CX42_VSI_BD[i]); - iowrite32(pci_offset, bridge->base + CA91CX42_VSI_TO[i]); - - /* Setup address space */ - temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M; - temp_ctl |= addr; - - /* Setup cycle types */ - temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M); - if (cycle & VME_SUPER) - temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR; - if (cycle & VME_USER) - temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV; - if (cycle & VME_PROG) - temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM; - if (cycle & VME_DATA) - temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA; - - /* Write ctl reg without enable */ - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - if (enabled) - temp_ctl |= CA91CX42_VSI_CTL_EN; - - iowrite32(temp_ctl, bridge->base + CA91CX42_VSI_CTL[i]); - - return 0; -} - -static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *pci_base, u32 *aspace, u32 *cycle) -{ - unsigned int i, granularity = 0, ctl = 0; - unsigned long long vme_bound, pci_offset; - struct ca91cx42_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - /* Read Registers */ - ctl = ioread32(bridge->base + CA91CX42_VSI_CTL[i]); - - *vme_base = ioread32(bridge->base + CA91CX42_VSI_BS[i]); - vme_bound = ioread32(bridge->base + CA91CX42_VSI_BD[i]); - pci_offset = ioread32(bridge->base + CA91CX42_VSI_TO[i]); - - *pci_base = (dma_addr_t)vme_base + pci_offset; - *size = (unsigned long long)((vme_bound - *vme_base) + granularity); - - *enabled = 0; - *aspace = 0; - *cycle = 0; - - if (ctl & CA91CX42_VSI_CTL_EN) - *enabled = 1; - - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16) - *aspace = VME_A16; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24) - *aspace = VME_A24; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32) - *aspace = VME_A32; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1) - *aspace = VME_USER1; - if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2) - *aspace = VME_USER2; - - if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR) - *cycle |= VME_SUPER; - if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV) - *cycle |= VME_USER; - if (ctl & CA91CX42_VSI_CTL_PGM_PGM) - *cycle |= VME_PROG; - if (ctl & CA91CX42_VSI_CTL_PGM_DATA) - *cycle |= VME_DATA; - - return 0; -} - -/* - * Allocate and map PCI Resource - */ -static int ca91cx42_alloc_resource(struct vme_master_resource *image, - unsigned long long size) -{ - unsigned long long existing_size; - int retval = 0; - struct pci_dev *pdev; - struct vme_bridge *ca91cx42_bridge; - - ca91cx42_bridge = image->parent; - - /* Find pci_dev container of dev */ - if (ca91cx42_bridge->parent == NULL) { - dev_err(ca91cx42_bridge->parent, "Dev entry NULL\n"); - return -EINVAL; - } - pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); - - existing_size = (unsigned long long)(image->bus_resource.end - - image->bus_resource.start); - - /* If the existing size is OK, return */ - if (existing_size == (size - 1)) - return 0; - - if (existing_size != 0) { - iounmap(image->kern_base); - image->kern_base = NULL; - kfree(image->bus_resource.name); - release_resource(&image->bus_resource); - memset(&image->bus_resource, 0, sizeof(struct resource)); - } - - if (image->bus_resource.name == NULL) { - image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); - if (image->bus_resource.name == NULL) { - dev_err(ca91cx42_bridge->parent, "Unable to allocate " - "memory for resource name\n"); - retval = -ENOMEM; - goto err_name; - } - } - - sprintf((char *)image->bus_resource.name, "%s.%d", - ca91cx42_bridge->name, image->number); - - image->bus_resource.start = 0; - image->bus_resource.end = (unsigned long)size; - image->bus_resource.flags = IORESOURCE_MEM; - - retval = pci_bus_alloc_resource(pdev->bus, - &image->bus_resource, size, size, PCIBIOS_MIN_MEM, - 0, NULL, NULL); - if (retval) { - dev_err(ca91cx42_bridge->parent, "Failed to allocate mem " - "resource for window %d size 0x%lx start 0x%lx\n", - image->number, (unsigned long)size, - (unsigned long)image->bus_resource.start); - goto err_resource; - } - - image->kern_base = ioremap_nocache( - image->bus_resource.start, size); - if (image->kern_base == NULL) { - dev_err(ca91cx42_bridge->parent, "Failed to remap resource\n"); - retval = -ENOMEM; - goto err_remap; - } - - return 0; - -err_remap: - release_resource(&image->bus_resource); -err_resource: - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -err_name: - return retval; -} - -/* - * Free and unmap PCI Resource - */ -static void ca91cx42_free_resource(struct vme_master_resource *image) -{ - iounmap(image->kern_base); - image->kern_base = NULL; - release_resource(&image->bus_resource); - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -} - - -static int ca91cx42_master_set(struct vme_master_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - int retval = 0; - unsigned int i, granularity = 0; - unsigned int temp_ctl = 0; - unsigned long long pci_bound, vme_offset, pci_base; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *bridge; - - ca91cx42_bridge = image->parent; - - bridge = ca91cx42_bridge->driver_priv; - - i = image->number; - - if ((i == 0) || (i == 4)) - granularity = 0x1000; - else - granularity = 0x10000; - - /* Verify input data */ - if (vme_base & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - if (size & (granularity - 1)) { - dev_err(ca91cx42_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - - spin_lock(&image->lock); - - /* - * Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependent stuff up the stack - */ - retval = ca91cx42_alloc_resource(image, size); - if (retval) { - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Unable to allocate memory " - "for resource name\n"); - retval = -ENOMEM; - goto err_res; - } - - pci_base = (unsigned long long)image->bus_resource.start; - - /* - * Bound address is a valid address for the window, adjust - * according to window granularity. - */ - pci_bound = pci_base + size; - vme_offset = vme_base - pci_base; - - /* Disable while we are mucking around */ - temp_ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); - temp_ctl &= ~CA91CX42_LSI_CTL_EN; - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - /* Setup cycle types */ - temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M; - if (cycle & VME_BLT) - temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT; - if (cycle & VME_MBLT) - temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT; - - /* Setup data width */ - temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M; - switch (dwidth) { - case VME_D8: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D8; - break; - case VME_D16: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D16; - break; - case VME_D32: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D32; - break; - case VME_D64: - temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; - break; - default: - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Invalid data width\n"); - retval = -EINVAL; - goto err_dwidth; - break; - } - - /* Setup address space */ - temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M; - switch (aspace) { - case VME_A16: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A16; - break; - case VME_A24: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A24; - break; - case VME_A32: - temp_ctl |= CA91CX42_LSI_CTL_VAS_A32; - break; - case VME_CRCSR: - temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR; - break; - case VME_USER1: - temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1; - break; - case VME_USER2: - temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2; - break; - case VME_A64: - case VME_USER3: - case VME_USER4: - default: - spin_unlock(&image->lock); - dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); - retval = -EINVAL; - goto err_aspace; - break; - } - - temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M); - if (cycle & VME_SUPER) - temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR; - if (cycle & VME_PROG) - temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM; - - /* Setup mapping */ - iowrite32(pci_base, bridge->base + CA91CX42_LSI_BS[i]); - iowrite32(pci_bound, bridge->base + CA91CX42_LSI_BD[i]); - iowrite32(vme_offset, bridge->base + CA91CX42_LSI_TO[i]); - - /* Write ctl reg without enable */ - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - if (enabled) - temp_ctl |= CA91CX42_LSI_CTL_EN; - - iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - - spin_unlock(&image->lock); - return 0; - -err_aspace: -err_dwidth: - ca91cx42_free_resource(image); -err_res: -err_window: - return retval; -} - -static int __ca91cx42_master_get(struct vme_master_resource *image, - int *enabled, unsigned long long *vme_base, unsigned long long *size, - u32 *aspace, u32 *cycle, u32 *dwidth) -{ - unsigned int i, ctl; - unsigned long long pci_base, pci_bound, vme_offset; - struct ca91cx42_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - ctl = ioread32(bridge->base + CA91CX42_LSI_CTL[i]); - - pci_base = ioread32(bridge->base + CA91CX42_LSI_BS[i]); - vme_offset = ioread32(bridge->base + CA91CX42_LSI_TO[i]); - pci_bound = ioread32(bridge->base + CA91CX42_LSI_BD[i]); - - *vme_base = pci_base + vme_offset; - *size = (unsigned long long)(pci_bound - pci_base); - - *enabled = 0; - *aspace = 0; - *cycle = 0; - *dwidth = 0; - - if (ctl & CA91CX42_LSI_CTL_EN) - *enabled = 1; - - /* Setup address space */ - switch (ctl & CA91CX42_LSI_CTL_VAS_M) { - case CA91CX42_LSI_CTL_VAS_A16: - *aspace = VME_A16; - break; - case CA91CX42_LSI_CTL_VAS_A24: - *aspace = VME_A24; - break; - case CA91CX42_LSI_CTL_VAS_A32: - *aspace = VME_A32; - break; - case CA91CX42_LSI_CTL_VAS_CRCSR: - *aspace = VME_CRCSR; - break; - case CA91CX42_LSI_CTL_VAS_USER1: - *aspace = VME_USER1; - break; - case CA91CX42_LSI_CTL_VAS_USER2: - *aspace = VME_USER2; - break; - } - - /* XXX Not sure howto check for MBLT */ - /* Setup cycle types */ - if (ctl & CA91CX42_LSI_CTL_VCT_BLT) - *cycle |= VME_BLT; - else - *cycle |= VME_SCT; - - if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR) - *cycle |= VME_SUPER; - else - *cycle |= VME_USER; - - if (ctl & CA91CX42_LSI_CTL_PGM_PGM) - *cycle = VME_PROG; - else - *cycle = VME_DATA; - - /* Setup data width */ - switch (ctl & CA91CX42_LSI_CTL_VDW_M) { - case CA91CX42_LSI_CTL_VDW_D8: - *dwidth = VME_D8; - break; - case CA91CX42_LSI_CTL_VDW_D16: - *dwidth = VME_D16; - break; - case CA91CX42_LSI_CTL_VDW_D32: - *dwidth = VME_D32; - break; - case CA91CX42_LSI_CTL_VDW_D64: - *dwidth = VME_D64; - break; - } - - return 0; -} - -static int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - int retval; - - spin_lock(&image->lock); - - retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); - - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t ca91cx42_master_read(struct vme_master_resource *image, - void *buf, size_t count, loff_t offset) -{ - ssize_t retval; - void *addr = image->kern_base + offset; - unsigned int done = 0; - unsigned int count32; - - if (count == 0) - return 0; - - spin_lock(&image->lock); - - /* The following code handles VME address alignment problem - * in order to assure the maximal data width cycle. - * We cannot use memcpy_xxx directly here because it - * may cut data transfer in 8-bits cycles, thus making - * D16 cycle impossible. - * From the other hand, the bridge itself assures that - * maximal configured data cycle is used and splits it - * automatically for non-aligned addresses. - */ - if ((uintptr_t)addr & 0x1) { - *(u8 *)buf = ioread8(addr); - done += 1; - if (done == count) - goto out; - } - if ((uintptr_t)addr & 0x2) { - if ((count - done) < 2) { - *(u8 *)(buf + done) = ioread8(addr + done); - done += 1; - goto out; - } else { - *(u16 *)(buf + done) = ioread16(addr + done); - done += 2; - } - } - - count32 = (count - done) & ~0x3; - if (count32 > 0) { - memcpy_fromio(buf + done, addr + done, (unsigned int)count); - done += count32; - } - - if ((count - done) & 0x2) { - *(u16 *)(buf + done) = ioread16(addr + done); - done += 2; - } - if ((count - done) & 0x1) { - *(u8 *)(buf + done) = ioread8(addr + done); - done += 1; - } -out: - retval = count; - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t ca91cx42_master_write(struct vme_master_resource *image, - void *buf, size_t count, loff_t offset) -{ - ssize_t retval; - void *addr = image->kern_base + offset; - unsigned int done = 0; - unsigned int count32; - - if (count == 0) - return 0; - - spin_lock(&image->lock); - - /* Here we apply for the same strategy we do in master_read - * function in order to assure D16 cycle when required. - */ - if ((uintptr_t)addr & 0x1) { - iowrite8(*(u8 *)buf, addr); - done += 1; - if (done == count) - goto out; - } - if ((uintptr_t)addr & 0x2) { - if ((count - done) < 2) { - iowrite8(*(u8 *)(buf + done), addr + done); - done += 1; - goto out; - } else { - iowrite16(*(u16 *)(buf + done), addr + done); - done += 2; - } - } - - count32 = (count - done) & ~0x3; - if (count32 > 0) { - memcpy_toio(addr + done, buf + done, count32); - done += count32; - } - - if ((count - done) & 0x2) { - iowrite16(*(u16 *)(buf + done), addr + done); - done += 2; - } - if ((count - done) & 0x1) { - iowrite8(*(u8 *)(buf + done), addr + done); - done += 1; - } -out: - retval = count; - - spin_unlock(&image->lock); - - return retval; -} - -static unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset) -{ - u32 result; - uintptr_t pci_addr; - int i; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = image->parent->driver_priv; - dev = image->parent->parent; - - /* Find the PCI address that maps to the desired VME address */ - i = image->number; - - /* Locking as we can only do one of these at a time */ - mutex_lock(&bridge->vme_rmw); - - /* Lock image */ - spin_lock(&image->lock); - - pci_addr = (uintptr_t)image->kern_base + offset; - - /* Address must be 4-byte aligned */ - if (pci_addr & 0x3) { - dev_err(dev, "RMW Address not 4-byte aligned\n"); - result = -EINVAL; - goto out; - } - - /* Ensure RMW Disabled whilst configuring */ - iowrite32(0, bridge->base + SCYC_CTL); - - /* Configure registers */ - iowrite32(mask, bridge->base + SCYC_EN); - iowrite32(compare, bridge->base + SCYC_CMP); - iowrite32(swap, bridge->base + SCYC_SWP); - iowrite32(pci_addr, bridge->base + SCYC_ADDR); - - /* Enable RMW */ - iowrite32(CA91CX42_SCYC_CTL_CYC_RMW, bridge->base + SCYC_CTL); - - /* Kick process off with a read to the required address. */ - result = ioread32(image->kern_base + offset); - - /* Disable RMW */ - iowrite32(0, bridge->base + SCYC_CTL); - -out: - spin_unlock(&image->lock); - - mutex_unlock(&bridge->vme_rmw); - - return result; -} - -static int ca91cx42_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) -{ - struct ca91cx42_dma_entry *entry, *prev; - struct vme_dma_pci *pci_attr; - struct vme_dma_vme *vme_attr; - dma_addr_t desc_ptr; - int retval = 0; - struct device *dev; - - dev = list->parent->parent->parent; - - /* XXX descriptor must be aligned on 64-bit boundaries */ - entry = kmalloc(sizeof(struct ca91cx42_dma_entry), GFP_KERNEL); - if (entry == NULL) { - dev_err(dev, "Failed to allocate memory for dma resource " - "structure\n"); - retval = -ENOMEM; - goto err_mem; - } - - /* Test descriptor alignment */ - if ((unsigned long)&entry->descriptor & CA91CX42_DCPP_M) { - dev_err(dev, "Descriptor not aligned to 16 byte boundary as " - "required: %p\n", &entry->descriptor); - retval = -EINVAL; - goto err_align; - } - - memset(&entry->descriptor, 0, sizeof(struct ca91cx42_dma_descriptor)); - - if (dest->type == VME_DMA_VME) { - entry->descriptor.dctl |= CA91CX42_DCTL_L2V; - vme_attr = dest->private; - pci_attr = src->private; - } else { - vme_attr = src->private; - pci_attr = dest->private; - } - - /* Check we can do fulfill required attributes */ - if ((vme_attr->aspace & ~(VME_A16 | VME_A24 | VME_A32 | VME_USER1 | - VME_USER2)) != 0) { - - dev_err(dev, "Unsupported cycle type\n"); - retval = -EINVAL; - goto err_aspace; - } - - if ((vme_attr->cycle & ~(VME_SCT | VME_BLT | VME_SUPER | VME_USER | - VME_PROG | VME_DATA)) != 0) { - - dev_err(dev, "Unsupported cycle type\n"); - retval = -EINVAL; - goto err_cycle; - } - - /* Check to see if we can fulfill source and destination */ - if (!(((src->type == VME_DMA_PCI) && (dest->type == VME_DMA_VME)) || - ((src->type == VME_DMA_VME) && (dest->type == VME_DMA_PCI)))) { - - dev_err(dev, "Cannot perform transfer with this " - "source-destination combination\n"); - retval = -EINVAL; - goto err_direct; - } - - /* Setup cycle types */ - if (vme_attr->cycle & VME_BLT) - entry->descriptor.dctl |= CA91CX42_DCTL_VCT_BLT; - - /* Setup data width */ - switch (vme_attr->dwidth) { - case VME_D8: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D8; - break; - case VME_D16: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D16; - break; - case VME_D32: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D32; - break; - case VME_D64: - entry->descriptor.dctl |= CA91CX42_DCTL_VDW_D64; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (vme_attr->aspace) { - case VME_A16: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A16; - break; - case VME_A24: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A24; - break; - case VME_A32: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_A32; - break; - case VME_USER1: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER1; - break; - case VME_USER2: - entry->descriptor.dctl |= CA91CX42_DCTL_VAS_USER2; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (vme_attr->cycle & VME_SUPER) - entry->descriptor.dctl |= CA91CX42_DCTL_SUPER_SUPR; - if (vme_attr->cycle & VME_PROG) - entry->descriptor.dctl |= CA91CX42_DCTL_PGM_PGM; - - entry->descriptor.dtbc = count; - entry->descriptor.dla = pci_attr->address; - entry->descriptor.dva = vme_attr->address; - entry->descriptor.dcpp = CA91CX42_DCPP_NULL; - - /* Add to list */ - list_add_tail(&entry->list, &list->entries); - - /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &list->entries) { - prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry, - list); - /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&entry->descriptor); - prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M; - } - - return 0; - -err_cycle: -err_aspace: -err_direct: -err_align: - kfree(entry); -err_mem: - return retval; -} - -static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - tmp = ioread32(bridge->base + DGCS); - - if (tmp & CA91CX42_DGCS_ACT) - return 0; - else - return 1; -} - -static int ca91cx42_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_dma_resource *ctrlr; - struct ca91cx42_dma_entry *entry; - int retval = 0; - dma_addr_t bus_addr; - u32 val; - struct device *dev; - struct ca91cx42_driver *bridge; - - ctrlr = list->parent; - - bridge = ctrlr->parent->driver_priv; - dev = ctrlr->parent->parent; - - mutex_lock(&ctrlr->mtx); - - if (!(list_empty(&ctrlr->running))) { - /* - * XXX We have an active DMA transfer and currently haven't - * sorted out the mechanism for "pending" DMA transfers. - * Return busy. - */ - /* Need to add to pending here */ - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } else { - list_add(&list->list, &ctrlr->running); - } - - /* Get first bus address and write into registers */ - entry = list_first_entry(&list->entries, struct ca91cx42_dma_entry, - list); - - bus_addr = virt_to_bus(&entry->descriptor); - - mutex_unlock(&ctrlr->mtx); - - iowrite32(0, bridge->base + DTBC); - iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP); - - /* Start the operation */ - val = ioread32(bridge->base + DGCS); - - /* XXX Could set VMEbus On and Off Counters here */ - val &= (CA91CX42_DGCS_VON_M | CA91CX42_DGCS_VOFF_M); - - val |= (CA91CX42_DGCS_CHAIN | CA91CX42_DGCS_STOP | CA91CX42_DGCS_HALT | - CA91CX42_DGCS_DONE | CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | - CA91CX42_DGCS_PERR); - - iowrite32(val, bridge->base + DGCS); - - val |= CA91CX42_DGCS_GO; - - iowrite32(val, bridge->base + DGCS); - - wait_event_interruptible(bridge->dma_queue, - ca91cx42_dma_busy(ctrlr->parent)); - - /* - * Read status register, this register is valid until we kick off a - * new transfer. - */ - val = ioread32(bridge->base + DGCS); - - if (val & (CA91CX42_DGCS_LERR | CA91CX42_DGCS_VERR | - CA91CX42_DGCS_PERR)) { - - dev_err(dev, "ca91c042: DMA Error. DGCS=%08X\n", val); - val = ioread32(bridge->base + DCTL); - } - - /* Remove list from running list */ - mutex_lock(&ctrlr->mtx); - list_del(&list->list); - mutex_unlock(&ctrlr->mtx); - - return retval; - -} - -static int ca91cx42_dma_list_empty(struct vme_dma_list *list) -{ - struct list_head *pos, *temp; - struct ca91cx42_dma_entry *entry; - - /* detach and free each entry */ - list_for_each_safe(pos, temp, &list->entries) { - list_del(pos); - entry = list_entry(pos, struct ca91cx42_dma_entry, list); - kfree(entry); - } - - return 0; -} - -/* - * All 4 location monitors reside at the same base - this is therefore a - * system wide configuration. - * - * This does not enable the LM monitor - that should be done when the first - * callback is attached and disabled when the last callback is removed. - */ -static int ca91cx42_lm_set(struct vme_lm_resource *lm, - unsigned long long lm_base, u32 aspace, u32 cycle) -{ - u32 temp_base, lm_ctl = 0; - int i; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = lm->parent->driver_priv; - dev = lm->parent->parent; - - /* Check the alignment of the location monitor */ - temp_base = (u32)lm_base; - if (temp_base & 0xffff) { - dev_err(dev, "Location monitor must be aligned to 64KB " - "boundary"); - return -EINVAL; - } - - mutex_lock(&lm->mtx); - - /* If we already have a callback attached, we can't move it! */ - for (i = 0; i < lm->monitors; i++) { - if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Location monitor callback attached, " - "can't reset\n"); - return -EBUSY; - } - } - - switch (aspace) { - case VME_A16: - lm_ctl |= CA91CX42_LM_CTL_AS_A16; - break; - case VME_A24: - lm_ctl |= CA91CX42_LM_CTL_AS_A24; - break; - case VME_A32: - lm_ctl |= CA91CX42_LM_CTL_AS_A32; - break; - default: - mutex_unlock(&lm->mtx); - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - lm_ctl |= CA91CX42_LM_CTL_SUPR; - if (cycle & VME_USER) - lm_ctl |= CA91CX42_LM_CTL_NPRIV; - if (cycle & VME_PROG) - lm_ctl |= CA91CX42_LM_CTL_PGM; - if (cycle & VME_DATA) - lm_ctl |= CA91CX42_LM_CTL_DATA; - - iowrite32(lm_base, bridge->base + LM_BS); - iowrite32(lm_ctl, bridge->base + LM_CTL); - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* Get configuration of the callback monitor and return whether it is enabled - * or disabled. - */ -static int ca91cx42_lm_get(struct vme_lm_resource *lm, - unsigned long long *lm_base, u32 *aspace, u32 *cycle) -{ - u32 lm_ctl, enabled = 0; - struct ca91cx42_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS); - lm_ctl = ioread32(bridge->base + LM_CTL); - - if (lm_ctl & CA91CX42_LM_CTL_EN) - enabled = 1; - - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A16) - *aspace = VME_A16; - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A24) - *aspace = VME_A24; - if ((lm_ctl & CA91CX42_LM_CTL_AS_M) == CA91CX42_LM_CTL_AS_A32) - *aspace = VME_A32; - - *cycle = 0; - if (lm_ctl & CA91CX42_LM_CTL_SUPR) - *cycle |= VME_SUPER; - if (lm_ctl & CA91CX42_LM_CTL_NPRIV) - *cycle |= VME_USER; - if (lm_ctl & CA91CX42_LM_CTL_PGM) - *cycle |= VME_PROG; - if (lm_ctl & CA91CX42_LM_CTL_DATA) - *cycle |= VME_DATA; - - mutex_unlock(&lm->mtx); - - return enabled; -} - -/* - * Attach a callback to a specific location monitor. - * - * Callback will be passed the monitor triggered. - */ -static int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, - void (*callback)(int)) -{ - u32 lm_ctl, tmp; - struct ca91cx42_driver *bridge; - struct device *dev; - - bridge = lm->parent->driver_priv; - dev = lm->parent->parent; - - mutex_lock(&lm->mtx); - - /* Ensure that the location monitor is configured - need PGM or DATA */ - lm_ctl = ioread32(bridge->base + LM_CTL); - if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Location monitor not properly configured\n"); - return -EINVAL; - } - - /* Check that a callback isn't already attached */ - if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(dev, "Existing callback attached\n"); - return -EBUSY; - } - - /* Attach callback */ - bridge->lm_callback[monitor] = callback; - - /* Enable Location Monitor interrupt */ - tmp = ioread32(bridge->base + LINT_EN); - tmp |= CA91CX42_LINT_LM[monitor]; - iowrite32(tmp, bridge->base + LINT_EN); - - /* Ensure that global Location Monitor Enable set */ - if ((lm_ctl & CA91CX42_LM_CTL_EN) == 0) { - lm_ctl |= CA91CX42_LM_CTL_EN; - iowrite32(lm_ctl, bridge->base + LM_CTL); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Detach a callback function forn a specific location monitor. - */ -static int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - /* Disable Location Monitor and ensure previous interrupts are clear */ - tmp = ioread32(bridge->base + LINT_EN); - tmp &= ~CA91CX42_LINT_LM[monitor]; - iowrite32(tmp, bridge->base + LINT_EN); - - iowrite32(CA91CX42_LINT_LM[monitor], - bridge->base + LINT_STAT); - - /* Detach callback */ - bridge->lm_callback[monitor] = NULL; - - /* If all location monitors disabled, disable global Location Monitor */ - if ((tmp & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 | - CA91CX42_LINT_LM3)) == 0) { - tmp = ioread32(bridge->base + LM_CTL); - tmp &= ~CA91CX42_LM_CTL_EN; - iowrite32(tmp, bridge->base + LM_CTL); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) -{ - u32 slot = 0; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - if (!geoid) { - slot = ioread32(bridge->base + VCSR_BS); - slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27); - } else - slot = geoid; - - return (int)slot; - -} - -void *ca91cx42_alloc_consistent(struct device *parent, size_t size, - dma_addr_t *dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - return pci_alloc_consistent(pdev, size, dma); -} - -void ca91cx42_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - pci_free_consistent(pdev, size, vaddr, dma); -} - -static int __init ca91cx42_init(void) -{ - return pci_register_driver(&ca91cx42_driver); -} - -/* - * Configure CR/CSR space - * - * Access to the CR/CSR can be configured at power-up. The location of the - * CR/CSR registers in the CR/CSR address space is determined by the boards - * Auto-ID or Geographic address. This function ensures that the window is - * enabled at an offset consistent with the boards geopgraphic address. - */ -static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge, - struct pci_dev *pdev) -{ - unsigned int crcsr_addr; - int tmp, slot; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - slot = ca91cx42_slot_get(ca91cx42_bridge); - - /* Write CSR Base Address if slot ID is supplied as a module param */ - if (geoid) - iowrite32(geoid << 27, bridge->base + VCSR_BS); - - dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot); - if (slot == 0) { - dev_err(&pdev->dev, "Slot number is unset, not configuring " - "CR/CSR space\n"); - return -EINVAL; - } - - /* Allocate mem for CR/CSR image */ - bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &bridge->crcsr_bus); - if (bridge->crcsr_kernel == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " - "image\n"); - return -ENOMEM; - } - - memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); - - crcsr_addr = slot * (512 * 1024); - iowrite32(bridge->crcsr_bus - crcsr_addr, bridge->base + VCSR_TO); - - tmp = ioread32(bridge->base + VCSR_CTL); - tmp |= CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, bridge->base + VCSR_CTL); - - return 0; -} - -static void ca91cx42_crcsr_exit(struct vme_bridge *ca91cx42_bridge, - struct pci_dev *pdev) -{ - u32 tmp; - struct ca91cx42_driver *bridge; - - bridge = ca91cx42_bridge->driver_priv; - - /* Turn off CR/CSR space */ - tmp = ioread32(bridge->base + VCSR_CTL); - tmp &= ~CA91CX42_VCSR_CTL_EN; - iowrite32(tmp, bridge->base + VCSR_CTL); - - /* Free image */ - iowrite32(0, bridge->base + VCSR_TO); - - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, - bridge->crcsr_bus); -} - -static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval, i; - u32 data; - struct list_head *pos = NULL; - struct vme_bridge *ca91cx42_bridge; - struct ca91cx42_driver *ca91cx42_device; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - - /* We want to support more than one of each bridge so we need to - * dynamically allocate the bridge structure - */ - ca91cx42_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); - - if (ca91cx42_bridge == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_struct; - } - - ca91cx42_device = kzalloc(sizeof(struct ca91cx42_driver), GFP_KERNEL); - - if (ca91cx42_device == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_driver; - } - - ca91cx42_bridge->driver_priv = ca91cx42_device; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err_enable; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* map registers in BAR 0 */ - ca91cx42_device->base = ioremap_nocache(pci_resource_start(pdev, 0), - 4096); - if (!ca91cx42_device->base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Check to see if the mapping worked out */ - data = ioread32(ca91cx42_device->base + CA91CX42_PCI_ID) & 0x0000FFFF; - if (data != PCI_VENDOR_ID_TUNDRA) { - dev_err(&pdev->dev, "PCI_ID check failed\n"); - retval = -EIO; - goto err_test; - } - - /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&ca91cx42_device->dma_queue); - init_waitqueue_head(&ca91cx42_device->iack_queue); - mutex_init(&ca91cx42_device->vme_int); - mutex_init(&ca91cx42_device->vme_rmw); - - ca91cx42_bridge->parent = &pdev->dev; - strcpy(ca91cx42_bridge->name, driver_name); - - /* Setup IRQ */ - retval = ca91cx42_irq_init(ca91cx42_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Initialization failed.\n"); - goto err_irq; - } - - /* Add master windows to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->master_resources); - for (i = 0; i < CA91C142_MAX_MASTER; i++) { - master_image = kmalloc(sizeof(struct vme_master_resource), - GFP_KERNEL); - if (master_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "master resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - master_image->parent = ca91cx42_bridge; - spin_lock_init(&master_image->lock); - master_image->locked = 0; - master_image->number = i; - master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_CRCSR | VME_USER1 | VME_USER2; - master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_SUPER | VME_USER | VME_PROG | VME_DATA; - master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; - memset(&master_image->bus_resource, 0, - sizeof(struct resource)); - master_image->kern_base = NULL; - list_add_tail(&master_image->list, - &ca91cx42_bridge->master_resources); - } - - /* Add slave windows to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->slave_resources); - for (i = 0; i < CA91C142_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(struct vme_slave_resource), - GFP_KERNEL); - if (slave_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "slave resource structure\n"); - retval = -ENOMEM; - goto err_slave; - } - slave_image->parent = ca91cx42_bridge; - mutex_init(&slave_image->mtx); - slave_image->locked = 0; - slave_image->number = i; - slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | - VME_USER2; - - /* Only windows 0 and 4 support A16 */ - if (i == 0 || i == 4) - slave_image->address_attr |= VME_A16; - - slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_SUPER | VME_USER | VME_PROG | VME_DATA; - list_add_tail(&slave_image->list, - &ca91cx42_bridge->slave_resources); - } - - /* Add dma engines to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->dma_resources); - for (i = 0; i < CA91C142_MAX_DMA; i++) { - dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), - GFP_KERNEL); - if (dma_ctrlr == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_dma; - } - dma_ctrlr->parent = ca91cx42_bridge; - mutex_init(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - dma_ctrlr->number = i; - dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | - VME_DMA_MEM_TO_VME; - INIT_LIST_HEAD(&dma_ctrlr->pending); - INIT_LIST_HEAD(&dma_ctrlr->running); - list_add_tail(&dma_ctrlr->list, - &ca91cx42_bridge->dma_resources); - } - - /* Add location monitor to list */ - INIT_LIST_HEAD(&ca91cx42_bridge->lm_resources); - lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); - if (lm == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "location monitor resource structure\n"); - retval = -ENOMEM; - goto err_lm; - } - lm->parent = ca91cx42_bridge; - mutex_init(&lm->mtx); - lm->locked = 0; - lm->number = 1; - lm->monitors = 4; - list_add_tail(&lm->list, &ca91cx42_bridge->lm_resources); - - ca91cx42_bridge->slave_get = ca91cx42_slave_get; - ca91cx42_bridge->slave_set = ca91cx42_slave_set; - ca91cx42_bridge->master_get = ca91cx42_master_get; - ca91cx42_bridge->master_set = ca91cx42_master_set; - ca91cx42_bridge->master_read = ca91cx42_master_read; - ca91cx42_bridge->master_write = ca91cx42_master_write; - ca91cx42_bridge->master_rmw = ca91cx42_master_rmw; - ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add; - ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec; - ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty; - ca91cx42_bridge->irq_set = ca91cx42_irq_set; - ca91cx42_bridge->irq_generate = ca91cx42_irq_generate; - ca91cx42_bridge->lm_set = ca91cx42_lm_set; - ca91cx42_bridge->lm_get = ca91cx42_lm_get; - ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; - ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; - ca91cx42_bridge->slot_get = ca91cx42_slot_get; - ca91cx42_bridge->alloc_consistent = ca91cx42_alloc_consistent; - ca91cx42_bridge->free_consistent = ca91cx42_free_consistent; - - data = ioread32(ca91cx42_device->base + MISC_CTL); - dev_info(&pdev->dev, "Board is%s the VME system controller\n", - (data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not"); - dev_info(&pdev->dev, "Slot ID is %d\n", - ca91cx42_slot_get(ca91cx42_bridge)); - - if (ca91cx42_crcsr_init(ca91cx42_bridge, pdev)) - dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - - /* Need to save ca91cx42_bridge pointer locally in link list for use in - * ca91cx42_remove() - */ - retval = vme_register_bridge(ca91cx42_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Registration failed.\n"); - goto err_reg; - } - - pci_set_drvdata(pdev, ca91cx42_bridge); - - return 0; - -err_reg: - ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); -err_lm: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } -err_dma: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } -err_slave: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } -err_master: - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - ca91cx42_irq_exit(ca91cx42_device, pdev); -err_irq: -err_test: - iounmap(ca91cx42_device->base); -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err_enable: - kfree(ca91cx42_device); -err_driver: - kfree(ca91cx42_bridge); -err_struct: - return retval; - -} - -static void ca91cx42_remove(struct pci_dev *pdev) -{ - struct list_head *pos = NULL; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - struct ca91cx42_driver *bridge; - struct vme_bridge *ca91cx42_bridge = pci_get_drvdata(pdev); - - bridge = ca91cx42_bridge->driver_priv; - - - /* Turn off Ints */ - iowrite32(0, bridge->base + LINT_EN); - - /* Turn off the windows */ - iowrite32(0x00800000, bridge->base + LSI0_CTL); - iowrite32(0x00800000, bridge->base + LSI1_CTL); - iowrite32(0x00800000, bridge->base + LSI2_CTL); - iowrite32(0x00800000, bridge->base + LSI3_CTL); - iowrite32(0x00800000, bridge->base + LSI4_CTL); - iowrite32(0x00800000, bridge->base + LSI5_CTL); - iowrite32(0x00800000, bridge->base + LSI6_CTL); - iowrite32(0x00800000, bridge->base + LSI7_CTL); - iowrite32(0x00F00000, bridge->base + VSI0_CTL); - iowrite32(0x00F00000, bridge->base + VSI1_CTL); - iowrite32(0x00F00000, bridge->base + VSI2_CTL); - iowrite32(0x00F00000, bridge->base + VSI3_CTL); - iowrite32(0x00F00000, bridge->base + VSI4_CTL); - iowrite32(0x00F00000, bridge->base + VSI5_CTL); - iowrite32(0x00F00000, bridge->base + VSI6_CTL); - iowrite32(0x00F00000, bridge->base + VSI7_CTL); - - vme_unregister_bridge(ca91cx42_bridge); - - ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } - - /* resources are stored in link list */ - list_for_each(pos, &ca91cx42_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - ca91cx42_irq_exit(bridge, pdev); - - iounmap(bridge->base); - - pci_release_regions(pdev); - - pci_disable_device(pdev); - - kfree(ca91cx42_bridge); -} - -static void __exit ca91cx42_exit(void) -{ - pci_unregister_driver(&ca91cx42_driver); -} - -MODULE_PARM_DESC(geoid, "Override geographical addressing"); -module_param(geoid, int, 0); - -MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); -MODULE_LICENSE("GPL"); - -module_init(ca91cx42_init); -module_exit(ca91cx42_exit); diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h deleted file mode 100644 index 02a7c79..0000000 --- a/drivers/staging/vme/bridges/vme_ca91cx42.h +++ /dev/null @@ -1,583 +0,0 @@ -/* - * ca91c042.h - * - * Support for the Tundra Universe 1 and Universe II VME bridge chips - * - * Author: Tom Armistead - * Updated by Ajit Prem - * Copyright 2004 Motorola Inc. - * - * Further updated by Martyn Welch <martyn.welch@ge.com> - * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc. - * - * Derived from ca91c042.h by Michael Wyrick - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef _CA91CX42_H -#define _CA91CX42_H - -#ifndef PCI_VENDOR_ID_TUNDRA -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#endif - -#ifndef PCI_DEVICE_ID_TUNDRA_CA91C142 -#define PCI_DEVICE_ID_TUNDRA_CA91C142 0x0000 -#endif - -/* - * Define the number of each that the CA91C142 supports. - */ -#define CA91C142_MAX_MASTER 8 /* Max Master Windows */ -#define CA91C142_MAX_SLAVE 8 /* Max Slave Windows */ -#define CA91C142_MAX_DMA 1 /* Max DMA Controllers */ -#define CA91C142_MAX_MAILBOX 4 /* Max Mail Box registers */ - -/* Structure used to hold driver specific information */ -struct ca91cx42_driver { - void __iomem *base; /* Base Address of device registers */ - wait_queue_head_t dma_queue; - wait_queue_head_t iack_queue; - wait_queue_head_t mbox_queue; - void (*lm_callback[4])(int); /* Called in interrupt handler */ - void *crcsr_kernel; - dma_addr_t crcsr_bus; - struct mutex vme_rmw; /* Only one RMW cycle at a time */ - struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ -}; - -/* See Page 2-77 in the Universe User Manual */ -struct ca91cx42_dma_descriptor { - unsigned int dctl; /* DMA Control */ - unsigned int dtbc; /* Transfer Byte Count */ - unsigned int dla; /* PCI Address */ - unsigned int res1; /* Reserved */ - unsigned int dva; /* Vme Address */ - unsigned int res2; /* Reserved */ - unsigned int dcpp; /* Pointer to Numed Cmd Packet with rPN */ - unsigned int res3; /* Reserved */ -}; - -struct ca91cx42_dma_entry { - struct ca91cx42_dma_descriptor descriptor; - struct list_head list; -}; - -/* Universe Register Offsets */ -/* general PCI configuration registers */ -#define CA91CX42_PCI_ID 0x000 -#define CA91CX42_PCI_CSR 0x004 -#define CA91CX42_PCI_CLASS 0x008 -#define CA91CX42_PCI_MISC0 0x00C -#define CA91CX42_PCI_BS 0x010 -#define CA91CX42_PCI_MISC1 0x03C - -#define LSI0_CTL 0x0100 -#define LSI0_BS 0x0104 -#define LSI0_BD 0x0108 -#define LSI0_TO 0x010C - -#define LSI1_CTL 0x0114 -#define LSI1_BS 0x0118 -#define LSI1_BD 0x011C -#define LSI1_TO 0x0120 - -#define LSI2_CTL 0x0128 -#define LSI2_BS 0x012C -#define LSI2_BD 0x0130 -#define LSI2_TO 0x0134 - -#define LSI3_CTL 0x013C -#define LSI3_BS 0x0140 -#define LSI3_BD 0x0144 -#define LSI3_TO 0x0148 - -#define LSI4_CTL 0x01A0 -#define LSI4_BS 0x01A4 -#define LSI4_BD 0x01A8 -#define LSI4_TO 0x01AC - -#define LSI5_CTL 0x01B4 -#define LSI5_BS 0x01B8 -#define LSI5_BD 0x01BC -#define LSI5_TO 0x01C0 - -#define LSI6_CTL 0x01C8 -#define LSI6_BS 0x01CC -#define LSI6_BD 0x01D0 -#define LSI6_TO 0x01D4 - -#define LSI7_CTL 0x01DC -#define LSI7_BS 0x01E0 -#define LSI7_BD 0x01E4 -#define LSI7_TO 0x01E8 - -static const int CA91CX42_LSI_CTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL, - LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL }; - -static const int CA91CX42_LSI_BS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS, - LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS }; - -static const int CA91CX42_LSI_BD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD, - LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD }; - -static const int CA91CX42_LSI_TO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO, - LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO }; - -#define SCYC_CTL 0x0170 -#define SCYC_ADDR 0x0174 -#define SCYC_EN 0x0178 -#define SCYC_CMP 0x017C -#define SCYC_SWP 0x0180 -#define LMISC 0x0184 -#define SLSI 0x0188 -#define L_CMDERR 0x018C -#define LAERR 0x0190 - -#define DCTL 0x0200 -#define DTBC 0x0204 -#define DLA 0x0208 -#define DVA 0x0210 -#define DCPP 0x0218 -#define DGCS 0x0220 -#define D_LLUE 0x0224 - -#define LINT_EN 0x0300 -#define LINT_STAT 0x0304 -#define LINT_MAP0 0x0308 -#define LINT_MAP1 0x030C -#define VINT_EN 0x0310 -#define VINT_STAT 0x0314 -#define VINT_MAP0 0x0318 -#define VINT_MAP1 0x031C -#define STATID 0x0320 - -#define V1_STATID 0x0324 -#define V2_STATID 0x0328 -#define V3_STATID 0x032C -#define V4_STATID 0x0330 -#define V5_STATID 0x0334 -#define V6_STATID 0x0338 -#define V7_STATID 0x033C - -static const int CA91CX42_V_STATID[8] = { 0, V1_STATID, V2_STATID, V3_STATID, - V4_STATID, V5_STATID, V6_STATID, - V7_STATID }; - -#define LINT_MAP2 0x0340 -#define VINT_MAP2 0x0344 - -#define MBOX0 0x0348 -#define MBOX1 0x034C -#define MBOX2 0x0350 -#define MBOX3 0x0354 -#define SEMA0 0x0358 -#define SEMA1 0x035C - -#define MAST_CTL 0x0400 -#define MISC_CTL 0x0404 -#define MISC_STAT 0x0408 -#define USER_AM 0x040C - -#define VSI0_CTL 0x0F00 -#define VSI0_BS 0x0F04 -#define VSI0_BD 0x0F08 -#define VSI0_TO 0x0F0C - -#define VSI1_CTL 0x0F14 -#define VSI1_BS 0x0F18 -#define VSI1_BD 0x0F1C -#define VSI1_TO 0x0F20 - -#define VSI2_CTL 0x0F28 -#define VSI2_BS 0x0F2C -#define VSI2_BD 0x0F30 -#define VSI2_TO 0x0F34 - -#define VSI3_CTL 0x0F3C -#define VSI3_BS 0x0F40 -#define VSI3_BD 0x0F44 -#define VSI3_TO 0x0F48 - -#define LM_CTL 0x0F64 -#define LM_BS 0x0F68 - -#define VRAI_CTL 0x0F70 - -#define VRAI_BS 0x0F74 -#define VCSR_CTL 0x0F80 -#define VCSR_TO 0x0F84 -#define V_AMERR 0x0F88 -#define VAERR 0x0F8C - -#define VSI4_CTL 0x0F90 -#define VSI4_BS 0x0F94 -#define VSI4_BD 0x0F98 -#define VSI4_TO 0x0F9C - -#define VSI5_CTL 0x0FA4 -#define VSI5_BS 0x0FA8 -#define VSI5_BD 0x0FAC -#define VSI5_TO 0x0FB0 - -#define VSI6_CTL 0x0FB8 -#define VSI6_BS 0x0FBC -#define VSI6_BD 0x0FC0 -#define VSI6_TO 0x0FC4 - -#define VSI7_CTL 0x0FCC -#define VSI7_BS 0x0FD0 -#define VSI7_BD 0x0FD4 -#define VSI7_TO 0x0FD8 - -static const int CA91CX42_VSI_CTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL, - VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL }; - -static const int CA91CX42_VSI_BS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS, - VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS }; - -static const int CA91CX42_VSI_BD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD, - VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD }; - -static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO, - VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO }; - -#define VCSR_CLR 0x0FF4 -#define VCSR_SET 0x0FF8 -#define VCSR_BS 0x0FFC - -/* - * PCI Class Register - * offset 008 - */ -#define CA91CX42_BM_PCI_CLASS_BASE 0xFF000000 -#define CA91CX42_OF_PCI_CLASS_BASE 24 -#define CA91CX42_BM_PCI_CLASS_SUB 0x00FF0000 -#define CA91CX42_OF_PCI_CLASS_SUB 16 -#define CA91CX42_BM_PCI_CLASS_PROG 0x0000FF00 -#define CA91CX42_OF_PCI_CLASS_PROG 8 -#define CA91CX42_BM_PCI_CLASS_RID 0x000000FF -#define CA91CX42_OF_PCI_CLASS_RID 0 - -#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_I 0 -#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_II 1 - -/* - * PCI Misc Register - * offset 00C - */ -#define CA91CX42_BM_PCI_MISC0_BISTC 0x80000000 -#define CA91CX42_BM_PCI_MISC0_SBIST 0x60000000 -#define CA91CX42_BM_PCI_MISC0_CCODE 0x0F000000 -#define CA91CX42_BM_PCI_MISC0_MFUNCT 0x00800000 -#define CA91CX42_BM_PCI_MISC0_LAYOUT 0x007F0000 -#define CA91CX42_BM_PCI_MISC0_LTIMER 0x0000FF00 -#define CA91CX42_OF_PCI_MISC0_LTIMER 8 - - -/* - * LSI Control Register - * offset 100 - */ -#define CA91CX42_LSI_CTL_EN (1<<31) -#define CA91CX42_LSI_CTL_PWEN (1<<30) - -#define CA91CX42_LSI_CTL_VDW_M (3<<22) -#define CA91CX42_LSI_CTL_VDW_D8 0 -#define CA91CX42_LSI_CTL_VDW_D16 (1<<22) -#define CA91CX42_LSI_CTL_VDW_D32 (1<<23) -#define CA91CX42_LSI_CTL_VDW_D64 (3<<22) - -#define CA91CX42_LSI_CTL_VAS_M (7<<16) -#define CA91CX42_LSI_CTL_VAS_A16 0 -#define CA91CX42_LSI_CTL_VAS_A24 (1<<16) -#define CA91CX42_LSI_CTL_VAS_A32 (1<<17) -#define CA91CX42_LSI_CTL_VAS_CRCSR (5<<16) -#define CA91CX42_LSI_CTL_VAS_USER1 (3<<17) -#define CA91CX42_LSI_CTL_VAS_USER2 (7<<16) - -#define CA91CX42_LSI_CTL_PGM_M (1<<14) -#define CA91CX42_LSI_CTL_PGM_DATA 0 -#define CA91CX42_LSI_CTL_PGM_PGM (1<<14) - -#define CA91CX42_LSI_CTL_SUPER_M (1<<12) -#define CA91CX42_LSI_CTL_SUPER_NPRIV 0 -#define CA91CX42_LSI_CTL_SUPER_SUPR (1<<12) - -#define CA91CX42_LSI_CTL_VCT_M (1<<8) -#define CA91CX42_LSI_CTL_VCT_BLT (1<<8) -#define CA91CX42_LSI_CTL_VCT_MBLT (1<<8) -#define CA91CX42_LSI_CTL_LAS (1<<0) - -/* - * SCYC_CTL Register - * offset 178 - */ -#define CA91CX42_SCYC_CTL_LAS_PCIMEM 0 -#define CA91CX42_SCYC_CTL_LAS_PCIIO (1<<2) - -#define CA91CX42_SCYC_CTL_CYC_M (3<<0) -#define CA91CX42_SCYC_CTL_CYC_RMW (1<<0) -#define CA91CX42_SCYC_CTL_CYC_ADOH (1<<1) - -/* - * LMISC Register - * offset 184 - */ -#define CA91CX42_BM_LMISC_CRT 0xF0000000 -#define CA91CX42_OF_LMISC_CRT 28 -#define CA91CX42_BM_LMISC_CWT 0x0F000000 -#define CA91CX42_OF_LMISC_CWT 24 - -/* - * SLSI Register - * offset 188 - */ -#define CA91CX42_BM_SLSI_EN 0x80000000 -#define CA91CX42_BM_SLSI_PWEN 0x40000000 -#define CA91CX42_BM_SLSI_VDW 0x00F00000 -#define CA91CX42_OF_SLSI_VDW 20 -#define CA91CX42_BM_SLSI_PGM 0x0000F000 -#define CA91CX42_OF_SLSI_PGM 12 -#define CA91CX42_BM_SLSI_SUPER 0x00000F00 -#define CA91CX42_OF_SLSI_SUPER 8 -#define CA91CX42_BM_SLSI_BS 0x000000F6 -#define CA91CX42_OF_SLSI_BS 2 -#define CA91CX42_BM_SLSI_LAS 0x00000003 -#define CA91CX42_OF_SLSI_LAS 0 -#define CA91CX42_BM_SLSI_RESERVED 0x3F0F0000 - -/* - * DCTL Register - * offset 200 - */ -#define CA91CX42_DCTL_L2V (1<<31) -#define CA91CX42_DCTL_VDW_M (3<<22) -#define CA91CX42_DCTL_VDW_M (3<<22) -#define CA91CX42_DCTL_VDW_D8 0 -#define CA91CX42_DCTL_VDW_D16 (1<<22) -#define CA91CX42_DCTL_VDW_D32 (1<<23) -#define CA91CX42_DCTL_VDW_D64 (3<<22) - -#define CA91CX42_DCTL_VAS_M (7<<16) -#define CA91CX42_DCTL_VAS_A16 0 -#define CA91CX42_DCTL_VAS_A24 (1<<16) -#define CA91CX42_DCTL_VAS_A32 (1<<17) -#define CA91CX42_DCTL_VAS_USER1 (3<<17) -#define CA91CX42_DCTL_VAS_USER2 (7<<16) - -#define CA91CX42_DCTL_PGM_M (1<<14) -#define CA91CX42_DCTL_PGM_DATA 0 -#define CA91CX42_DCTL_PGM_PGM (1<<14) - -#define CA91CX42_DCTL_SUPER_M (1<<12) -#define CA91CX42_DCTL_SUPER_NPRIV 0 -#define CA91CX42_DCTL_SUPER_SUPR (1<<12) - -#define CA91CX42_DCTL_VCT_M (1<<8) -#define CA91CX42_DCTL_VCT_BLT (1<<8) -#define CA91CX42_DCTL_LD64EN (1<<7) - -/* - * DCPP Register - * offset 218 - */ -#define CA91CX42_DCPP_M 0xf -#define CA91CX42_DCPP_NULL (1<<0) - -/* - * DMA General Control/Status Register (DGCS) - * offset 220 - */ -#define CA91CX42_DGCS_GO (1<<31) -#define CA91CX42_DGCS_STOP_REQ (1<<30) -#define CA91CX42_DGCS_HALT_REQ (1<<29) -#define CA91CX42_DGCS_CHAIN (1<<27) - -#define CA91CX42_DGCS_VON_M (7<<20) - -#define CA91CX42_DGCS_VOFF_M (0xf<<16) - -#define CA91CX42_DGCS_ACT (1<<15) -#define CA91CX42_DGCS_STOP (1<<14) -#define CA91CX42_DGCS_HALT (1<<13) -#define CA91CX42_DGCS_DONE (1<<11) -#define CA91CX42_DGCS_LERR (1<<10) -#define CA91CX42_DGCS_VERR (1<<9) -#define CA91CX42_DGCS_PERR (1<<8) -#define CA91CX42_DGCS_INT_STOP (1<<6) -#define CA91CX42_DGCS_INT_HALT (1<<5) -#define CA91CX42_DGCS_INT_DONE (1<<3) -#define CA91CX42_DGCS_INT_LERR (1<<2) -#define CA91CX42_DGCS_INT_VERR (1<<1) -#define CA91CX42_DGCS_INT_PERR (1<<0) - -/* - * PCI Interrupt Enable Register - * offset 300 - */ -#define CA91CX42_LINT_LM3 0x00800000 -#define CA91CX42_LINT_LM2 0x00400000 -#define CA91CX42_LINT_LM1 0x00200000 -#define CA91CX42_LINT_LM0 0x00100000 -#define CA91CX42_LINT_MBOX3 0x00080000 -#define CA91CX42_LINT_MBOX2 0x00040000 -#define CA91CX42_LINT_MBOX1 0x00020000 -#define CA91CX42_LINT_MBOX0 0x00010000 -#define CA91CX42_LINT_ACFAIL 0x00008000 -#define CA91CX42_LINT_SYSFAIL 0x00004000 -#define CA91CX42_LINT_SW_INT 0x00002000 -#define CA91CX42_LINT_SW_IACK 0x00001000 - -#define CA91CX42_LINT_VERR 0x00000400 -#define CA91CX42_LINT_LERR 0x00000200 -#define CA91CX42_LINT_DMA 0x00000100 -#define CA91CX42_LINT_VIRQ7 0x00000080 -#define CA91CX42_LINT_VIRQ6 0x00000040 -#define CA91CX42_LINT_VIRQ5 0x00000020 -#define CA91CX42_LINT_VIRQ4 0x00000010 -#define CA91CX42_LINT_VIRQ3 0x00000008 -#define CA91CX42_LINT_VIRQ2 0x00000004 -#define CA91CX42_LINT_VIRQ1 0x00000002 -#define CA91CX42_LINT_VOWN 0x00000001 - -static const int CA91CX42_LINT_VIRQ[] = { 0, CA91CX42_LINT_VIRQ1, - CA91CX42_LINT_VIRQ2, CA91CX42_LINT_VIRQ3, - CA91CX42_LINT_VIRQ4, CA91CX42_LINT_VIRQ5, - CA91CX42_LINT_VIRQ6, CA91CX42_LINT_VIRQ7 }; - -#define CA91CX42_LINT_MBOX 0x000F0000 - -static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1, - CA91CX42_LINT_LM2, CA91CX42_LINT_LM3 }; - -/* - * MAST_CTL Register - * offset 400 - */ -#define CA91CX42_BM_MAST_CTL_MAXRTRY 0xF0000000 -#define CA91CX42_OF_MAST_CTL_MAXRTRY 28 -#define CA91CX42_BM_MAST_CTL_PWON 0x0F000000 -#define CA91CX42_OF_MAST_CTL_PWON 24 -#define CA91CX42_BM_MAST_CTL_VRL 0x00C00000 -#define CA91CX42_OF_MAST_CTL_VRL 22 -#define CA91CX42_BM_MAST_CTL_VRM 0x00200000 -#define CA91CX42_BM_MAST_CTL_VREL 0x00100000 -#define CA91CX42_BM_MAST_CTL_VOWN 0x00080000 -#define CA91CX42_BM_MAST_CTL_VOWN_ACK 0x00040000 -#define CA91CX42_BM_MAST_CTL_PABS 0x00001000 -#define CA91CX42_BM_MAST_CTL_BUS_NO 0x0000000F -#define CA91CX42_OF_MAST_CTL_BUS_NO 0 - -/* - * MISC_CTL Register - * offset 404 - */ -#define CA91CX42_MISC_CTL_VBTO 0xF0000000 -#define CA91CX42_MISC_CTL_VARB 0x04000000 -#define CA91CX42_MISC_CTL_VARBTO 0x03000000 -#define CA91CX42_MISC_CTL_SW_LRST 0x00800000 -#define CA91CX42_MISC_CTL_SW_SRST 0x00400000 -#define CA91CX42_MISC_CTL_BI 0x00100000 -#define CA91CX42_MISC_CTL_ENGBI 0x00080000 -#define CA91CX42_MISC_CTL_RESCIND 0x00040000 -#define CA91CX42_MISC_CTL_SYSCON 0x00020000 -#define CA91CX42_MISC_CTL_V64AUTO 0x00010000 -#define CA91CX42_MISC_CTL_RESERVED 0x0820FFFF - -#define CA91CX42_OF_MISC_CTL_VARBTO 24 -#define CA91CX42_OF_MISC_CTL_VBTO 28 - -/* - * MISC_STAT Register - * offset 408 - */ -#define CA91CX42_BM_MISC_STAT_ENDIAN 0x80000000 -#define CA91CX42_BM_MISC_STAT_LCLSIZE 0x40000000 -#define CA91CX42_BM_MISC_STAT_DY4AUTO 0x08000000 -#define CA91CX42_BM_MISC_STAT_MYBBSY 0x00200000 -#define CA91CX42_BM_MISC_STAT_DY4DONE 0x00080000 -#define CA91CX42_BM_MISC_STAT_TXFE 0x00040000 -#define CA91CX42_BM_MISC_STAT_RXFE 0x00020000 -#define CA91CX42_BM_MISC_STAT_DY4AUTOID 0x0000FF00 -#define CA91CX42_OF_MISC_STAT_DY4AUTOID 8 - -/* - * VSI Control Register - * offset F00 - */ -#define CA91CX42_VSI_CTL_EN (1<<31) -#define CA91CX42_VSI_CTL_PWEN (1<<30) -#define CA91CX42_VSI_CTL_PREN (1<<29) - -#define CA91CX42_VSI_CTL_PGM_M (3<<22) -#define CA91CX42_VSI_CTL_PGM_DATA (1<<22) -#define CA91CX42_VSI_CTL_PGM_PGM (1<<23) - -#define CA91CX42_VSI_CTL_SUPER_M (3<<20) -#define CA91CX42_VSI_CTL_SUPER_NPRIV (1<<20) -#define CA91CX42_VSI_CTL_SUPER_SUPR (1<<21) - -#define CA91CX42_VSI_CTL_VAS_M (7<<16) -#define CA91CX42_VSI_CTL_VAS_A16 0 -#define CA91CX42_VSI_CTL_VAS_A24 (1<<16) -#define CA91CX42_VSI_CTL_VAS_A32 (1<<17) -#define CA91CX42_VSI_CTL_VAS_USER1 (3<<17) -#define CA91CX42_VSI_CTL_VAS_USER2 (7<<16) - -#define CA91CX42_VSI_CTL_LD64EN (1<<7) -#define CA91CX42_VSI_CTL_LLRMW (1<<6) - -#define CA91CX42_VSI_CTL_LAS_M (3<<0) -#define CA91CX42_VSI_CTL_LAS_PCI_MS 0 -#define CA91CX42_VSI_CTL_LAS_PCI_IO (1<<0) -#define CA91CX42_VSI_CTL_LAS_PCI_CONF (1<<1) - -/* LM_CTL Register - * offset F64 - */ -#define CA91CX42_LM_CTL_EN (1<<31) -#define CA91CX42_LM_CTL_PGM (1<<23) -#define CA91CX42_LM_CTL_DATA (1<<22) -#define CA91CX42_LM_CTL_SUPR (1<<21) -#define CA91CX42_LM_CTL_NPRIV (1<<20) -#define CA91CX42_LM_CTL_AS_M (5<<16) -#define CA91CX42_LM_CTL_AS_A16 0 -#define CA91CX42_LM_CTL_AS_A24 (1<<16) -#define CA91CX42_LM_CTL_AS_A32 (1<<17) - -/* - * VRAI_CTL Register - * offset F70 - */ -#define CA91CX42_BM_VRAI_CTL_EN 0x80000000 -#define CA91CX42_BM_VRAI_CTL_PGM 0x00C00000 -#define CA91CX42_OF_VRAI_CTL_PGM 22 -#define CA91CX42_BM_VRAI_CTL_SUPER 0x00300000 -#define CA91CX42_OF_VRAI_CTL_SUPER 20 -#define CA91CX42_BM_VRAI_CTL_VAS 0x00030000 -#define CA91CX42_OF_VRAI_CTL_VAS 16 - -/* VCSR_CTL Register - * offset F80 - */ -#define CA91CX42_VCSR_CTL_EN (1<<31) - -#define CA91CX42_VCSR_CTL_LAS_M (3<<0) -#define CA91CX42_VCSR_CTL_LAS_PCI_MS 0 -#define CA91CX42_VCSR_CTL_LAS_PCI_IO (1<<0) -#define CA91CX42_VCSR_CTL_LAS_PCI_CONF (1<<1) - -/* VCSR_BS Register - * offset FFC - */ -#define CA91CX42_VCSR_BS_SLOT_M (0x1F<<27) - -#endif /* _CA91CX42_H */ diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c deleted file mode 100644 index f505821..0000000 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ /dev/null @@ -1,2660 +0,0 @@ -/* - * Support for the Tundra TSI148 VME-PCI Bridge Chip - * - * Author: Martyn Welch <martyn.welch@ge.com> - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/mm.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/proc_fs.h> -#include <linux/pci.h> -#include <linux/poll.h> -#include <linux/dma-mapping.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/time.h> -#include <linux/io.h> -#include <linux/uaccess.h> - -#include "../vme.h" -#include "../vme_bridge.h" -#include "vme_tsi148.h" - -static int __init tsi148_init(void); -static int tsi148_probe(struct pci_dev *, const struct pci_device_id *); -static void tsi148_remove(struct pci_dev *); -static void __exit tsi148_exit(void); - - -/* Module parameter */ -static bool err_chk; -static int geoid; - -static const char driver_name[] = "vme_tsi148"; - -static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, - { }, -}; - -static struct pci_driver tsi148_driver = { - .name = driver_name, - .id_table = tsi148_ids, - .probe = tsi148_probe, - .remove = tsi148_remove, -}; - -static void reg_join(unsigned int high, unsigned int low, - unsigned long long *variable) -{ - *variable = (unsigned long long)high << 32; - *variable |= (unsigned long long)low; -} - -static void reg_split(unsigned long long variable, unsigned int *high, - unsigned int *low) -{ - *low = (unsigned int)variable & 0xFFFFFFFF; - *high = (unsigned int)(variable >> 32); -} - -/* - * Wakes up DMA queue. - */ -static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge, - int channel_mask) -{ - u32 serviced = 0; - - if (channel_mask & TSI148_LCSR_INTS_DMA0S) { - wake_up(&bridge->dma_queue[0]); - serviced |= TSI148_LCSR_INTC_DMA0C; - } - if (channel_mask & TSI148_LCSR_INTS_DMA1S) { - wake_up(&bridge->dma_queue[1]); - serviced |= TSI148_LCSR_INTC_DMA1C; - } - - return serviced; -} - -/* - * Wake up location monitor queue - */ -static u32 tsi148_LM_irqhandler(struct tsi148_driver *bridge, u32 stat) -{ - int i; - u32 serviced = 0; - - for (i = 0; i < 4; i++) { - if (stat & TSI148_LCSR_INTS_LMS[i]) { - /* We only enable interrupts if the callback is set */ - bridge->lm_callback[i](i); - serviced |= TSI148_LCSR_INTC_LMC[i]; - } - } - - return serviced; -} - -/* - * Wake up mail box queue. - * - * XXX This functionality is not exposed up though API. - */ -static u32 tsi148_MB_irqhandler(struct vme_bridge *tsi148_bridge, u32 stat) -{ - int i; - u32 val; - u32 serviced = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - for (i = 0; i < 4; i++) { - if (stat & TSI148_LCSR_INTS_MBS[i]) { - val = ioread32be(bridge->base + TSI148_GCSR_MBOX[i]); - dev_err(tsi148_bridge->parent, "VME Mailbox %d received" - ": 0x%x\n", i, val); - serviced |= TSI148_LCSR_INTC_MBC[i]; - } - } - - return serviced; -} - -/* - * Display error & status message when PERR (PCI) exception interrupt occurs. - */ -static u32 tsi148_PERR_irqhandler(struct vme_bridge *tsi148_bridge) -{ - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - dev_err(tsi148_bridge->parent, "PCI Exception at address: 0x%08x:%08x, " - "attributes: %08x\n", - ioread32be(bridge->base + TSI148_LCSR_EDPAU), - ioread32be(bridge->base + TSI148_LCSR_EDPAL), - ioread32be(bridge->base + TSI148_LCSR_EDPAT)); - - dev_err(tsi148_bridge->parent, "PCI-X attribute reg: %08x, PCI-X split " - "completion reg: %08x\n", - ioread32be(bridge->base + TSI148_LCSR_EDPXA), - ioread32be(bridge->base + TSI148_LCSR_EDPXS)); - - iowrite32be(TSI148_LCSR_EDPAT_EDPCL, bridge->base + TSI148_LCSR_EDPAT); - - return TSI148_LCSR_INTC_PERRC; -} - -/* - * Save address and status when VME error interrupt occurs. - */ -static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) -{ - unsigned int error_addr_high, error_addr_low; - unsigned long long error_addr; - u32 error_attrib; - struct vme_bus_error *error; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - error_addr_high = ioread32be(bridge->base + TSI148_LCSR_VEAU); - error_addr_low = ioread32be(bridge->base + TSI148_LCSR_VEAL); - error_attrib = ioread32be(bridge->base + TSI148_LCSR_VEAT); - - reg_join(error_addr_high, error_addr_low, &error_addr); - - /* Check for exception register overflow (we have lost error data) */ - if (error_attrib & TSI148_LCSR_VEAT_VEOF) { - dev_err(tsi148_bridge->parent, "VME Bus Exception Overflow " - "Occurred\n"); - } - - error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); - if (error) { - error->address = error_addr; - error->attributes = error_attrib; - list_add_tail(&error->list, &tsi148_bridge->vme_errors); - } else { - dev_err(tsi148_bridge->parent, "Unable to alloc memory for " - "VMEbus Error reporting\n"); - dev_err(tsi148_bridge->parent, "VME Bus Error at address: " - "0x%llx, attributes: %08x\n", error_addr, error_attrib); - } - - /* Clear Status */ - iowrite32be(TSI148_LCSR_VEAT_VESCL, bridge->base + TSI148_LCSR_VEAT); - - return TSI148_LCSR_INTC_VERRC; -} - -/* - * Wake up IACK queue. - */ -static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge) -{ - wake_up(&bridge->iack_queue); - - return TSI148_LCSR_INTC_IACKC; -} - -/* - * Calling VME bus interrupt callback if provided. - */ -static u32 tsi148_VIRQ_irqhandler(struct vme_bridge *tsi148_bridge, - u32 stat) -{ - int vec, i, serviced = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - for (i = 7; i > 0; i--) { - if (stat & (1 << i)) { - /* - * Note: Even though the registers are defined as - * 32-bits in the spec, we only want to issue 8-bit - * IACK cycles on the bus, read from offset 3. - */ - vec = ioread8(bridge->base + TSI148_LCSR_VIACK[i] + 3); - - vme_irq_handler(tsi148_bridge, i, vec); - - serviced |= (1 << i); - } - } - - return serviced; -} - -/* - * Top level interrupt handler. Clears appropriate interrupt status bits and - * then calls appropriate sub handler(s). - */ -static irqreturn_t tsi148_irqhandler(int irq, void *ptr) -{ - u32 stat, enable, serviced = 0; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = ptr; - - bridge = tsi148_bridge->driver_priv; - - /* Determine which interrupts are unmasked and set */ - enable = ioread32be(bridge->base + TSI148_LCSR_INTEO); - stat = ioread32be(bridge->base + TSI148_LCSR_INTS); - - /* Only look at unmasked interrupts */ - stat &= enable; - - if (unlikely(!stat)) - return IRQ_NONE; - - /* Call subhandlers as appropriate */ - /* DMA irqs */ - if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S)) - serviced |= tsi148_DMA_irqhandler(bridge, stat); - - /* Location monitor irqs */ - if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S | - TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S)) - serviced |= tsi148_LM_irqhandler(bridge, stat); - - /* Mail box irqs */ - if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S | - TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S)) - serviced |= tsi148_MB_irqhandler(tsi148_bridge, stat); - - /* PCI bus error */ - if (stat & TSI148_LCSR_INTS_PERRS) - serviced |= tsi148_PERR_irqhandler(tsi148_bridge); - - /* VME bus error */ - if (stat & TSI148_LCSR_INTS_VERRS) - serviced |= tsi148_VERR_irqhandler(tsi148_bridge); - - /* IACK irq */ - if (stat & TSI148_LCSR_INTS_IACKS) - serviced |= tsi148_IACK_irqhandler(bridge); - - /* VME bus irqs */ - if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S | - TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S | - TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S | - TSI148_LCSR_INTS_IRQ1S)) - serviced |= tsi148_VIRQ_irqhandler(tsi148_bridge, stat); - - /* Clear serviced interrupts */ - iowrite32be(serviced, bridge->base + TSI148_LCSR_INTC); - - return IRQ_HANDLED; -} - -static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) -{ - int result; - unsigned int tmp; - struct pci_dev *pdev; - struct tsi148_driver *bridge; - - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - - bridge = tsi148_bridge->driver_priv; - - /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&tsi148_bridge->vme_errors); - - mutex_init(&tsi148_bridge->irq_mtx); - - result = request_irq(pdev->irq, - tsi148_irqhandler, - IRQF_SHARED, - driver_name, tsi148_bridge); - if (result) { - dev_err(tsi148_bridge->parent, "Can't get assigned pci irq " - "vector %02X\n", pdev->irq); - return result; - } - - /* Enable and unmask interrupts */ - tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO | - TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO | - TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO | - TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO | - TSI148_LCSR_INTEO_IACKEO; - - /* This leaves the following interrupts masked. - * TSI148_LCSR_INTEO_VIEEO - * TSI148_LCSR_INTEO_SYSFLEO - * TSI148_LCSR_INTEO_ACFLEO - */ - - /* Don't enable Location Monitor interrupts here - they will be - * enabled when the location monitors are properly configured and - * a callback has been attached. - * TSI148_LCSR_INTEO_LM0EO - * TSI148_LCSR_INTEO_LM1EO - * TSI148_LCSR_INTEO_LM2EO - * TSI148_LCSR_INTEO_LM3EO - */ - - /* Don't enable VME interrupts until we add a handler, else the board - * will respond to it and we don't want that unless it knows how to - * properly deal with it. - * TSI148_LCSR_INTEO_IRQ7EO - * TSI148_LCSR_INTEO_IRQ6EO - * TSI148_LCSR_INTEO_IRQ5EO - * TSI148_LCSR_INTEO_IRQ4EO - * TSI148_LCSR_INTEO_IRQ3EO - * TSI148_LCSR_INTEO_IRQ2EO - * TSI148_LCSR_INTEO_IRQ1EO - */ - - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - return 0; -} - -static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - struct tsi148_driver *bridge = tsi148_bridge->driver_priv; - - /* Turn off interrupts */ - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO); - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN); - - /* Clear all interrupts */ - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC); - - /* Detach interrupt handler */ - free_irq(pdev->irq, tsi148_bridge); -} - -/* - * Check to see if an IACk has been received, return true (1) or false (0). - */ -static int tsi148_iack_received(struct tsi148_driver *bridge) -{ - u32 tmp; - - tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); - - if (tmp & TSI148_LCSR_VICR_IRQS) - return 0; - else - return 1; -} - -/* - * Configure VME interrupt - */ -static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, - int state, int sync) -{ - struct pci_dev *pdev; - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* We need to do the ordering differently for enabling and disabling */ - if (state == 0) { - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - if (sync != 0) { - pdev = container_of(tsi148_bridge->parent, - struct pci_dev, dev); - - synchronize_irq(pdev->irq); - } - } else { - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - } -} - -/* - * Generate a VME bus interrupt at the requested level & vector. Wait for - * interrupt to be acked. - */ -static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, - int statid) -{ - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&bridge->vme_int); - - /* Read VICR register */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); - - /* Set Status/ID */ - tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) | - (statid & TSI148_LCSR_VICR_STID_M); - iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); - - /* Assert VMEbus IRQ */ - tmp = tmp | TSI148_LCSR_VICR_IRQL[level]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VICR); - - /* XXX Consider implementing a timeout? */ - wait_event_interruptible(bridge->iack_queue, - tsi148_iack_received(bridge)); - - mutex_unlock(&bridge->vme_int); - - return 0; -} - -/* - * Find the first error in this address range - */ -static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, - u32 aspace, unsigned long long address, size_t count) -{ - struct list_head *err_pos; - struct vme_bus_error *vme_err, *valid = NULL; - unsigned long long bound; - - bound = address + count; - - /* - * XXX We are currently not looking at the address space when parsing - * for errors. This is because parsing the Address Modifier Codes - * is going to be quite resource intensive to do properly. We - * should be OK just looking at the addresses and this is certainly - * much better than what we had before. - */ - err_pos = NULL; - /* Iterate through errors */ - list_for_each(err_pos, &tsi148_bridge->vme_errors) { - vme_err = list_entry(err_pos, struct vme_bus_error, list); - if ((vme_err->address >= address) && - (vme_err->address < bound)) { - - valid = vme_err; - break; - } - } - - return valid; -} - -/* - * Clear errors in the provided address range. - */ -static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, - u32 aspace, unsigned long long address, size_t count) -{ - struct list_head *err_pos, *temp; - struct vme_bus_error *vme_err; - unsigned long long bound; - - bound = address + count; - - /* - * XXX We are currently not looking at the address space when parsing - * for errors. This is because parsing the Address Modifier Codes - * is going to be quite resource intensive to do properly. We - * should be OK just looking at the addresses and this is certainly - * much better than what we had before. - */ - err_pos = NULL; - /* Iterate through errors */ - list_for_each_safe(err_pos, temp, &tsi148_bridge->vme_errors) { - vme_err = list_entry(err_pos, struct vme_bus_error, list); - - if ((vme_err->address >= address) && - (vme_err->address < bound)) { - - list_del(err_pos); - kfree(vme_err); - } - } -} - -/* - * Initialize a slave window with the requested attributes. - */ -static int tsi148_slave_set(struct vme_slave_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t pci_base, u32 aspace, u32 cycle) -{ - unsigned int i, addr = 0, granularity = 0; - unsigned int temp_ctl = 0; - unsigned int vme_base_low, vme_base_high; - unsigned int vme_bound_low, vme_bound_high; - unsigned int pci_offset_low, pci_offset_high; - unsigned long long vme_bound, pci_offset; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - bridge = tsi148_bridge->driver_priv; - - i = image->number; - - switch (aspace) { - case VME_A16: - granularity = 0x10; - addr |= TSI148_LCSR_ITAT_AS_A16; - break; - case VME_A24: - granularity = 0x1000; - addr |= TSI148_LCSR_ITAT_AS_A24; - break; - case VME_A32: - granularity = 0x10000; - addr |= TSI148_LCSR_ITAT_AS_A32; - break; - case VME_A64: - granularity = 0x10000; - addr |= TSI148_LCSR_ITAT_AS_A64; - break; - case VME_CRCSR: - case VME_USER1: - case VME_USER2: - case VME_USER3: - case VME_USER4: - default: - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_split(vme_base, &vme_base_high, &vme_base_low); - - /* - * Bound address is a valid address for the window, adjust - * accordingly - */ - vme_bound = vme_base + size - granularity; - reg_split(vme_bound, &vme_bound_high, &vme_bound_low); - pci_offset = (unsigned long long)pci_base - vme_base; - reg_split(pci_offset, &pci_offset_high, &pci_offset_low); - - if (vme_base_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid VME base alignment\n"); - return -EINVAL; - } - if (vme_bound_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid VME bound alignment\n"); - return -EINVAL; - } - if (pci_offset_low & (granularity - 1)) { - dev_err(tsi148_bridge->parent, "Invalid PCI Offset " - "alignment\n"); - return -EINVAL; - } - - /* Disable while we are mucking around */ - temp_ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - temp_ctl &= ~TSI148_LCSR_ITAT_EN; - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - /* Setup mapping */ - iowrite32be(vme_base_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAU); - iowrite32be(vme_base_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAL); - iowrite32be(vme_bound_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAU); - iowrite32be(vme_bound_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAL); - iowrite32be(pci_offset_high, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFU); - iowrite32be(pci_offset_low, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFL); - - /* Setup 2eSST speeds */ - temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M; - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160; - break; - case VME_2eSST267: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267; - break; - case VME_2eSST320: - temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - temp_ctl &= ~(0x1F << 7); - if (cycle & VME_BLT) - temp_ctl |= TSI148_LCSR_ITAT_BLT; - if (cycle & VME_MBLT) - temp_ctl |= TSI148_LCSR_ITAT_MBLT; - if (cycle & VME_2eVME) - temp_ctl |= TSI148_LCSR_ITAT_2eVME; - if (cycle & VME_2eSST) - temp_ctl |= TSI148_LCSR_ITAT_2eSST; - if (cycle & VME_2eSSTB) - temp_ctl |= TSI148_LCSR_ITAT_2eSSTB; - - /* Setup address space */ - temp_ctl &= ~TSI148_LCSR_ITAT_AS_M; - temp_ctl |= addr; - - temp_ctl &= ~0xF; - if (cycle & VME_SUPER) - temp_ctl |= TSI148_LCSR_ITAT_SUPR ; - if (cycle & VME_USER) - temp_ctl |= TSI148_LCSR_ITAT_NPRIV; - if (cycle & VME_PROG) - temp_ctl |= TSI148_LCSR_ITAT_PGM; - if (cycle & VME_DATA) - temp_ctl |= TSI148_LCSR_ITAT_DATA; - - /* Write ctl reg without enable */ - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - if (enabled) - temp_ctl |= TSI148_LCSR_ITAT_EN; - - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - return 0; -} - -/* - * Get slave window configuration. - */ -static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *pci_base, u32 *aspace, u32 *cycle) -{ - unsigned int i, granularity = 0, ctl = 0; - unsigned int vme_base_low, vme_base_high; - unsigned int vme_bound_low, vme_bound_high; - unsigned int pci_offset_low, pci_offset_high; - unsigned long long vme_bound, pci_offset; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - /* Read registers */ - ctl = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - - vme_base_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAU); - vme_base_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITSAL); - vme_bound_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAU); - vme_bound_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITEAL); - pci_offset_high = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFU); - pci_offset_low = ioread32be(bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITOFL); - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_join(vme_base_high, vme_base_low, vme_base); - reg_join(vme_bound_high, vme_bound_low, &vme_bound); - reg_join(pci_offset_high, pci_offset_low, &pci_offset); - - *pci_base = (dma_addr_t)vme_base + pci_offset; - - *enabled = 0; - *aspace = 0; - *cycle = 0; - - if (ctl & TSI148_LCSR_ITAT_EN) - *enabled = 1; - - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) { - granularity = 0x10; - *aspace |= VME_A16; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) { - granularity = 0x1000; - *aspace |= VME_A24; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) { - granularity = 0x10000; - *aspace |= VME_A32; - } - if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) { - granularity = 0x10000; - *aspace |= VME_A64; - } - - /* Need granularity before we set the size */ - *size = (unsigned long long)((vme_bound - *vme_base) + granularity); - - - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160) - *cycle |= VME_2eSST160; - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267) - *cycle |= VME_2eSST267; - if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320) - *cycle |= VME_2eSST320; - - if (ctl & TSI148_LCSR_ITAT_BLT) - *cycle |= VME_BLT; - if (ctl & TSI148_LCSR_ITAT_MBLT) - *cycle |= VME_MBLT; - if (ctl & TSI148_LCSR_ITAT_2eVME) - *cycle |= VME_2eVME; - if (ctl & TSI148_LCSR_ITAT_2eSST) - *cycle |= VME_2eSST; - if (ctl & TSI148_LCSR_ITAT_2eSSTB) - *cycle |= VME_2eSSTB; - - if (ctl & TSI148_LCSR_ITAT_SUPR) - *cycle |= VME_SUPER; - if (ctl & TSI148_LCSR_ITAT_NPRIV) - *cycle |= VME_USER; - if (ctl & TSI148_LCSR_ITAT_PGM) - *cycle |= VME_PROG; - if (ctl & TSI148_LCSR_ITAT_DATA) - *cycle |= VME_DATA; - - return 0; -} - -/* - * Allocate and map PCI Resource - */ -static int tsi148_alloc_resource(struct vme_master_resource *image, - unsigned long long size) -{ - unsigned long long existing_size; - int retval = 0; - struct pci_dev *pdev; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = image->parent; - - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); - - existing_size = (unsigned long long)(image->bus_resource.end - - image->bus_resource.start); - - /* If the existing size is OK, return */ - if ((size != 0) && (existing_size == (size - 1))) - return 0; - - if (existing_size != 0) { - iounmap(image->kern_base); - image->kern_base = NULL; - kfree(image->bus_resource.name); - release_resource(&image->bus_resource); - memset(&image->bus_resource, 0, sizeof(struct resource)); - } - - /* Exit here if size is zero */ - if (size == 0) - return 0; - - if (image->bus_resource.name == NULL) { - image->bus_resource.name = kmalloc(VMENAMSIZ+3, GFP_ATOMIC); - if (image->bus_resource.name == NULL) { - dev_err(tsi148_bridge->parent, "Unable to allocate " - "memory for resource name\n"); - retval = -ENOMEM; - goto err_name; - } - } - - sprintf((char *)image->bus_resource.name, "%s.%d", tsi148_bridge->name, - image->number); - - image->bus_resource.start = 0; - image->bus_resource.end = (unsigned long)size; - image->bus_resource.flags = IORESOURCE_MEM; - - retval = pci_bus_alloc_resource(pdev->bus, - &image->bus_resource, size, size, PCIBIOS_MIN_MEM, - 0, NULL, NULL); - if (retval) { - dev_err(tsi148_bridge->parent, "Failed to allocate mem " - "resource for window %d size 0x%lx start 0x%lx\n", - image->number, (unsigned long)size, - (unsigned long)image->bus_resource.start); - goto err_resource; - } - - image->kern_base = ioremap_nocache( - image->bus_resource.start, size); - if (image->kern_base == NULL) { - dev_err(tsi148_bridge->parent, "Failed to remap resource\n"); - retval = -ENOMEM; - goto err_remap; - } - - return 0; - -err_remap: - release_resource(&image->bus_resource); -err_resource: - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -err_name: - return retval; -} - -/* - * Free and unmap PCI Resource - */ -static void tsi148_free_resource(struct vme_master_resource *image) -{ - iounmap(image->kern_base); - image->kern_base = NULL; - release_resource(&image->bus_resource); - kfree(image->bus_resource.name); - memset(&image->bus_resource, 0, sizeof(struct resource)); -} - -/* - * Set the attributes of an outbound window. - */ -static int tsi148_master_set(struct vme_master_resource *image, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - int retval = 0; - unsigned int i; - unsigned int temp_ctl = 0; - unsigned int pci_base_low, pci_base_high; - unsigned int pci_bound_low, pci_bound_high; - unsigned int vme_offset_low, vme_offset_high; - unsigned long long pci_bound, vme_offset, pci_base; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - - bridge = tsi148_bridge->driver_priv; - - /* Verify input data */ - if (vme_base & 0xFFFF) { - dev_err(tsi148_bridge->parent, "Invalid VME Window " - "alignment\n"); - retval = -EINVAL; - goto err_window; - } - - if ((size == 0) && (enabled != 0)) { - dev_err(tsi148_bridge->parent, "Size must be non-zero for " - "enabled windows\n"); - retval = -EINVAL; - goto err_window; - } - - spin_lock(&image->lock); - - /* Let's allocate the resource here rather than further up the stack as - * it avoids pushing loads of bus dependent stuff up the stack. If size - * is zero, any existing resource will be freed. - */ - retval = tsi148_alloc_resource(image, size); - if (retval) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Unable to allocate memory for " - "resource\n"); - goto err_res; - } - - if (size == 0) { - pci_base = 0; - pci_bound = 0; - vme_offset = 0; - } else { - pci_base = (unsigned long long)image->bus_resource.start; - - /* - * Bound address is a valid address for the window, adjust - * according to window granularity. - */ - pci_bound = pci_base + (size - 0x10000); - vme_offset = vme_base - pci_base; - } - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_split(pci_base, &pci_base_high, &pci_base_low); - reg_split(pci_bound, &pci_bound_high, &pci_bound_low); - reg_split(vme_offset, &vme_offset_high, &vme_offset_low); - - if (pci_base_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n"); - retval = -EINVAL; - goto err_gran; - } - if (pci_bound_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n"); - retval = -EINVAL; - goto err_gran; - } - if (vme_offset_low & 0xFFFF) { - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid VME Offset " - "alignment\n"); - retval = -EINVAL; - goto err_gran; - } - - i = image->number; - - /* Disable while we are mucking around */ - temp_ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - temp_ctl &= ~TSI148_LCSR_OTAT_EN; - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - /* Setup 2eSST speeds */ - temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M; - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160; - break; - case VME_2eSST267: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267; - break; - case VME_2eSST320: - temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_BLT) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_BLT; - } - if (cycle & VME_MBLT) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT; - } - if (cycle & VME_2eVME) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME; - } - if (cycle & VME_2eSST) { - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; - } - if (cycle & VME_2eSSTB) { - dev_warn(tsi148_bridge->parent, "Currently not setting " - "Broadcast Select Registers\n"); - temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; - temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; - } - - /* Setup data width */ - temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M; - switch (dwidth) { - case VME_D16: - temp_ctl |= TSI148_LCSR_OTAT_DBW_16; - break; - case VME_D32: - temp_ctl |= TSI148_LCSR_OTAT_DBW_32; - break; - default: - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid data width\n"); - retval = -EINVAL; - goto err_dwidth; - } - - /* Setup address space */ - temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M; - switch (aspace) { - case VME_A16: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16; - break; - case VME_A24: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24; - break; - case VME_A32: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32; - break; - case VME_A64: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64; - break; - case VME_CRCSR: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR; - break; - case VME_USER1: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1; - break; - case VME_USER2: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2; - break; - case VME_USER3: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3; - break; - case VME_USER4: - temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4; - break; - default: - spin_unlock(&image->lock); - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - retval = -EINVAL; - goto err_aspace; - break; - } - - temp_ctl &= ~(3<<4); - if (cycle & VME_SUPER) - temp_ctl |= TSI148_LCSR_OTAT_SUP; - if (cycle & VME_PROG) - temp_ctl |= TSI148_LCSR_OTAT_PGM; - - /* Setup mapping */ - iowrite32be(pci_base_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - iowrite32be(pci_base_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - iowrite32be(pci_bound_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAU); - iowrite32be(pci_bound_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAL); - iowrite32be(vme_offset_high, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFU); - iowrite32be(vme_offset_low, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFL); - - /* Write ctl reg without enable */ - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - if (enabled) - temp_ctl |= TSI148_LCSR_OTAT_EN; - - iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - spin_unlock(&image->lock); - return 0; - -err_aspace: -err_dwidth: -err_gran: - tsi148_free_resource(image); -err_res: -err_window: - return retval; - -} - -/* - * Set the attributes of an outbound window. - * - * XXX Not parsing prefetch information. - */ -static int __tsi148_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - unsigned int i, ctl; - unsigned int pci_base_low, pci_base_high; - unsigned int pci_bound_low, pci_bound_high; - unsigned int vme_offset_low, vme_offset_high; - - unsigned long long pci_base, pci_bound, vme_offset; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - i = image->number; - - ctl = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - - pci_base_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - pci_base_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - pci_bound_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAU); - pci_bound_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTEAL); - vme_offset_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFU); - vme_offset_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTOFL); - - /* Convert 64-bit variables to 2x 32-bit variables */ - reg_join(pci_base_high, pci_base_low, &pci_base); - reg_join(pci_bound_high, pci_bound_low, &pci_bound); - reg_join(vme_offset_high, vme_offset_low, &vme_offset); - - *vme_base = pci_base + vme_offset; - *size = (unsigned long long)(pci_bound - pci_base) + 0x10000; - - *enabled = 0; - *aspace = 0; - *cycle = 0; - *dwidth = 0; - - if (ctl & TSI148_LCSR_OTAT_EN) - *enabled = 1; - - /* Setup address space */ - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16) - *aspace |= VME_A16; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24) - *aspace |= VME_A24; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32) - *aspace |= VME_A32; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64) - *aspace |= VME_A64; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR) - *aspace |= VME_CRCSR; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1) - *aspace |= VME_USER1; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2) - *aspace |= VME_USER2; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3) - *aspace |= VME_USER3; - if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4) - *aspace |= VME_USER4; - - /* Setup 2eSST speeds */ - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160) - *cycle |= VME_2eSST160; - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267) - *cycle |= VME_2eSST267; - if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320) - *cycle |= VME_2eSST320; - - /* Setup cycle types */ - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_SCT) - *cycle |= VME_SCT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_BLT) - *cycle |= VME_BLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_MBLT) - *cycle |= VME_MBLT; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eVME) - *cycle |= VME_2eVME; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSST) - *cycle |= VME_2eSST; - if ((ctl & TSI148_LCSR_OTAT_TM_M) == TSI148_LCSR_OTAT_TM_2eSSTB) - *cycle |= VME_2eSSTB; - - if (ctl & TSI148_LCSR_OTAT_SUP) - *cycle |= VME_SUPER; - else - *cycle |= VME_USER; - - if (ctl & TSI148_LCSR_OTAT_PGM) - *cycle |= VME_PROG; - else - *cycle |= VME_DATA; - - /* Setup data width */ - if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16) - *dwidth = VME_D16; - if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32) - *dwidth = VME_D32; - - return 0; -} - - -static int tsi148_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - int retval; - - spin_lock(&image->lock); - - retval = __tsi148_master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); - - spin_unlock(&image->lock); - - return retval; -} - -static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) -{ - int retval, enabled; - unsigned long long vme_base, size; - u32 aspace, cycle, dwidth; - struct vme_bus_error *vme_err = NULL; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = image->parent; - - spin_lock(&image->lock); - - memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); - retval = count; - - if (!err_chk) - goto skip_chk; - - __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, - &dwidth); - - vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, - count); - if (vme_err != NULL) { - dev_err(image->parent->parent, "First VME read error detected " - "an at address 0x%llx\n", vme_err->address); - retval = vme_err->address - (vme_base + offset); - /* Clear down save errors in this address range */ - tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, - count); - } - -skip_chk: - spin_unlock(&image->lock); - - return retval; -} - - -static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) -{ - int retval = 0, enabled; - unsigned long long vme_base, size; - u32 aspace, cycle, dwidth; - - struct vme_bus_error *vme_err = NULL; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = image->parent; - - bridge = tsi148_bridge->driver_priv; - - spin_lock(&image->lock); - - memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); - retval = count; - - /* - * Writes are posted. We need to do a read on the VME bus to flush out - * all of the writes before we check for errors. We can't guarantee - * that reading the data we have just written is safe. It is believed - * that there isn't any read, write re-ordering, so we can read any - * location in VME space, so lets read the Device ID from the tsi148's - * own registers as mapped into CR/CSR space. - * - * We check for saved errors in the written address range/space. - */ - - if (!err_chk) - goto skip_chk; - - /* - * Get window info first, to maximise the time that the buffers may - * fluch on their own - */ - __tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle, - &dwidth); - - ioread16(bridge->flush_image->kern_base + 0x7F000); - - vme_err = tsi148_find_error(tsi148_bridge, aspace, vme_base + offset, - count); - if (vme_err != NULL) { - dev_warn(tsi148_bridge->parent, "First VME write error detected" - " an at address 0x%llx\n", vme_err->address); - retval = vme_err->address - (vme_base + offset); - /* Clear down save errors in this address range */ - tsi148_clear_errors(tsi148_bridge, aspace, vme_base + offset, - count); - } - -skip_chk: - spin_unlock(&image->lock); - - return retval; -} - -/* - * Perform an RMW cycle on the VME bus. - * - * Requires a previously configured master window, returns final value. - */ -static unsigned int tsi148_master_rmw(struct vme_master_resource *image, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset) -{ - unsigned long long pci_addr; - unsigned int pci_addr_high, pci_addr_low; - u32 tmp, result; - int i; - struct tsi148_driver *bridge; - - bridge = image->parent->driver_priv; - - /* Find the PCI address that maps to the desired VME address */ - i = image->number; - - /* Locking as we can only do one of these at a time */ - mutex_lock(&bridge->vme_rmw); - - /* Lock image */ - spin_lock(&image->lock); - - pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAU); - pci_addr_low = ioread32be(bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTSAL); - - reg_join(pci_addr_high, pci_addr_low, &pci_addr); - reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low); - - /* Configure registers */ - iowrite32be(mask, bridge->base + TSI148_LCSR_RMWEN); - iowrite32be(compare, bridge->base + TSI148_LCSR_RMWC); - iowrite32be(swap, bridge->base + TSI148_LCSR_RMWS); - iowrite32be(pci_addr_high, bridge->base + TSI148_LCSR_RMWAU); - iowrite32be(pci_addr_low, bridge->base + TSI148_LCSR_RMWAL); - - /* Enable RMW */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); - tmp |= TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); - - /* Kick process off with a read to the required address. */ - result = ioread32be(image->kern_base + offset); - - /* Disable RMW */ - tmp = ioread32be(bridge->base + TSI148_LCSR_VMCTRL); - tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); - - spin_unlock(&image->lock); - - mutex_unlock(&bridge->vme_rmw); - - return result; -} - -static int tsi148_dma_set_vme_src_attributes(struct device *dev, u32 *attr, - u32 aspace, u32 cycle, u32 dwidth) -{ - /* Setup 2eSST speeds */ - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - *attr |= TSI148_LCSR_DSAT_2eSSTM_160; - break; - case VME_2eSST267: - *attr |= TSI148_LCSR_DSAT_2eSSTM_267; - break; - case VME_2eSST320: - *attr |= TSI148_LCSR_DSAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_SCT) - *attr |= TSI148_LCSR_DSAT_TM_SCT; - - if (cycle & VME_BLT) - *attr |= TSI148_LCSR_DSAT_TM_BLT; - - if (cycle & VME_MBLT) - *attr |= TSI148_LCSR_DSAT_TM_MBLT; - - if (cycle & VME_2eVME) - *attr |= TSI148_LCSR_DSAT_TM_2eVME; - - if (cycle & VME_2eSST) - *attr |= TSI148_LCSR_DSAT_TM_2eSST; - - if (cycle & VME_2eSSTB) { - dev_err(dev, "Currently not setting Broadcast Select " - "Registers\n"); - *attr |= TSI148_LCSR_DSAT_TM_2eSSTB; - } - - /* Setup data width */ - switch (dwidth) { - case VME_D16: - *attr |= TSI148_LCSR_DSAT_DBW_16; - break; - case VME_D32: - *attr |= TSI148_LCSR_DSAT_DBW_32; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (aspace) { - case VME_A16: - *attr |= TSI148_LCSR_DSAT_AMODE_A16; - break; - case VME_A24: - *attr |= TSI148_LCSR_DSAT_AMODE_A24; - break; - case VME_A32: - *attr |= TSI148_LCSR_DSAT_AMODE_A32; - break; - case VME_A64: - *attr |= TSI148_LCSR_DSAT_AMODE_A64; - break; - case VME_CRCSR: - *attr |= TSI148_LCSR_DSAT_AMODE_CRCSR; - break; - case VME_USER1: - *attr |= TSI148_LCSR_DSAT_AMODE_USER1; - break; - case VME_USER2: - *attr |= TSI148_LCSR_DSAT_AMODE_USER2; - break; - case VME_USER3: - *attr |= TSI148_LCSR_DSAT_AMODE_USER3; - break; - case VME_USER4: - *attr |= TSI148_LCSR_DSAT_AMODE_USER4; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - *attr |= TSI148_LCSR_DSAT_SUP; - if (cycle & VME_PROG) - *attr |= TSI148_LCSR_DSAT_PGM; - - return 0; -} - -static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, - u32 aspace, u32 cycle, u32 dwidth) -{ - /* Setup 2eSST speeds */ - switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) { - case VME_2eSST160: - *attr |= TSI148_LCSR_DDAT_2eSSTM_160; - break; - case VME_2eSST267: - *attr |= TSI148_LCSR_DDAT_2eSSTM_267; - break; - case VME_2eSST320: - *attr |= TSI148_LCSR_DDAT_2eSSTM_320; - break; - } - - /* Setup cycle types */ - if (cycle & VME_SCT) - *attr |= TSI148_LCSR_DDAT_TM_SCT; - - if (cycle & VME_BLT) - *attr |= TSI148_LCSR_DDAT_TM_BLT; - - if (cycle & VME_MBLT) - *attr |= TSI148_LCSR_DDAT_TM_MBLT; - - if (cycle & VME_2eVME) - *attr |= TSI148_LCSR_DDAT_TM_2eVME; - - if (cycle & VME_2eSST) - *attr |= TSI148_LCSR_DDAT_TM_2eSST; - - if (cycle & VME_2eSSTB) { - dev_err(dev, "Currently not setting Broadcast Select " - "Registers\n"); - *attr |= TSI148_LCSR_DDAT_TM_2eSSTB; - } - - /* Setup data width */ - switch (dwidth) { - case VME_D16: - *attr |= TSI148_LCSR_DDAT_DBW_16; - break; - case VME_D32: - *attr |= TSI148_LCSR_DDAT_DBW_32; - break; - default: - dev_err(dev, "Invalid data width\n"); - return -EINVAL; - } - - /* Setup address space */ - switch (aspace) { - case VME_A16: - *attr |= TSI148_LCSR_DDAT_AMODE_A16; - break; - case VME_A24: - *attr |= TSI148_LCSR_DDAT_AMODE_A24; - break; - case VME_A32: - *attr |= TSI148_LCSR_DDAT_AMODE_A32; - break; - case VME_A64: - *attr |= TSI148_LCSR_DDAT_AMODE_A64; - break; - case VME_CRCSR: - *attr |= TSI148_LCSR_DDAT_AMODE_CRCSR; - break; - case VME_USER1: - *attr |= TSI148_LCSR_DDAT_AMODE_USER1; - break; - case VME_USER2: - *attr |= TSI148_LCSR_DDAT_AMODE_USER2; - break; - case VME_USER3: - *attr |= TSI148_LCSR_DDAT_AMODE_USER3; - break; - case VME_USER4: - *attr |= TSI148_LCSR_DDAT_AMODE_USER4; - break; - default: - dev_err(dev, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - *attr |= TSI148_LCSR_DDAT_SUP; - if (cycle & VME_PROG) - *attr |= TSI148_LCSR_DDAT_PGM; - - return 0; -} - -/* - * Add a link list descriptor to the list - */ -static int tsi148_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) -{ - struct tsi148_dma_entry *entry, *prev; - u32 address_high, address_low; - struct vme_dma_pattern *pattern_attr; - struct vme_dma_pci *pci_attr; - struct vme_dma_vme *vme_attr; - dma_addr_t desc_ptr; - int retval = 0; - struct vme_bridge *tsi148_bridge; - - tsi148_bridge = list->parent->parent; - - /* Descriptor must be aligned on 64-bit boundaries */ - entry = kmalloc(sizeof(struct tsi148_dma_entry), GFP_KERNEL); - if (entry == NULL) { - dev_err(tsi148_bridge->parent, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_mem; - } - - /* Test descriptor alignment */ - if ((unsigned long)&entry->descriptor & 0x7) { - dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 " - "byte boundary as required: %p\n", - &entry->descriptor); - retval = -EINVAL; - goto err_align; - } - - /* Given we are going to fill out the structure, we probably don't - * need to zero it, but better safe than sorry for now. - */ - memset(&entry->descriptor, 0, sizeof(struct tsi148_dma_descriptor)); - - /* Fill out source part */ - switch (src->type) { - case VME_DMA_PATTERN: - pattern_attr = src->private; - - entry->descriptor.dsal = pattern_attr->pattern; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT; - /* Default behaviour is 32 bit pattern */ - if (pattern_attr->type & VME_DMA_PATTERN_BYTE) - entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ; - - /* It seems that the default behaviour is to increment */ - if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) - entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN; - - break; - case VME_DMA_PCI: - pci_attr = src->private; - - reg_split((unsigned long long)pci_attr->address, &address_high, - &address_low); - entry->descriptor.dsau = address_high; - entry->descriptor.dsal = address_low; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI; - break; - case VME_DMA_VME: - vme_attr = src->private; - - reg_split((unsigned long long)vme_attr->address, &address_high, - &address_low); - entry->descriptor.dsau = address_high; - entry->descriptor.dsal = address_low; - entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME; - - retval = tsi148_dma_set_vme_src_attributes( - tsi148_bridge->parent, &entry->descriptor.dsat, - vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if (retval < 0) - goto err_source; - break; - default: - dev_err(tsi148_bridge->parent, "Invalid source type\n"); - retval = -EINVAL; - goto err_source; - break; - } - - /* Assume last link - this will be over-written by adding another */ - entry->descriptor.dnlau = 0; - entry->descriptor.dnlal = TSI148_LCSR_DNLAL_LLA; - - - /* Fill out destination part */ - switch (dest->type) { - case VME_DMA_PCI: - pci_attr = dest->private; - - reg_split((unsigned long long)pci_attr->address, &address_high, - &address_low); - entry->descriptor.ddau = address_high; - entry->descriptor.ddal = address_low; - entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI; - break; - case VME_DMA_VME: - vme_attr = dest->private; - - reg_split((unsigned long long)vme_attr->address, &address_high, - &address_low); - entry->descriptor.ddau = address_high; - entry->descriptor.ddal = address_low; - entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME; - - retval = tsi148_dma_set_vme_dest_attributes( - tsi148_bridge->parent, &entry->descriptor.ddat, - vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); - if (retval < 0) - goto err_dest; - break; - default: - dev_err(tsi148_bridge->parent, "Invalid destination type\n"); - retval = -EINVAL; - goto err_dest; - break; - } - - /* Fill out count */ - entry->descriptor.dcnt = (u32)count; - - /* Add to list */ - list_add_tail(&entry->list, &list->entries); - - /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &list->entries) { - prev = list_entry(entry->list.prev, struct tsi148_dma_entry, - list); - /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&entry->descriptor); - reg_split(desc_ptr, &prev->descriptor.dnlau, - &prev->descriptor.dnlal); - } - - return 0; - -err_dest: -err_source: -err_align: - kfree(entry); -err_mem: - return retval; -} - -/* - * Check to see if the provided DMA channel is busy. - */ -static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel) -{ - u32 tmp; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - tmp = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - - if (tmp & TSI148_LCSR_DSTA_BSY) - return 0; - else - return 1; - -} - -/* - * Execute a previously generated link list - * - * XXX Need to provide control register configuration. - */ -static int tsi148_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_dma_resource *ctrlr; - int channel, retval = 0; - struct tsi148_dma_entry *entry; - dma_addr_t bus_addr; - u32 bus_addr_high, bus_addr_low; - u32 val, dctlreg = 0; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - ctrlr = list->parent; - - tsi148_bridge = ctrlr->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&ctrlr->mtx); - - channel = ctrlr->number; - - if (!list_empty(&ctrlr->running)) { - /* - * XXX We have an active DMA transfer and currently haven't - * sorted out the mechanism for "pending" DMA transfers. - * Return busy. - */ - /* Need to add to pending here */ - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } else { - list_add(&list->list, &ctrlr->running); - } - - /* Get first bus address and write into registers */ - entry = list_first_entry(&list->entries, struct tsi148_dma_entry, - list); - - bus_addr = virt_to_bus(&entry->descriptor); - - mutex_unlock(&ctrlr->mtx); - - reg_split(bus_addr, &bus_addr_high, &bus_addr_low); - - iowrite32be(bus_addr_high, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU); - iowrite32be(bus_addr_low, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL); - - /* Start the operation */ - iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, bridge->base + - TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL); - - wait_event_interruptible(bridge->dma_queue[channel], - tsi148_dma_busy(ctrlr->parent, channel)); - /* - * Read status register, this register is valid until we kick off a - * new transfer. - */ - val = ioread32be(bridge->base + TSI148_LCSR_DMA[channel] + - TSI148_LCSR_OFFSET_DSTA); - - if (val & TSI148_LCSR_DSTA_VBE) { - dev_err(tsi148_bridge->parent, "DMA Error. DSTA=%08X\n", val); - retval = -EIO; - } - - /* Remove list from running list */ - mutex_lock(&ctrlr->mtx); - list_del(&list->list); - mutex_unlock(&ctrlr->mtx); - - return retval; -} - -/* - * Clean up a previously generated link list - * - * We have a separate function, don't assume that the chain can't be reused. - */ -static int tsi148_dma_list_empty(struct vme_dma_list *list) -{ - struct list_head *pos, *temp; - struct tsi148_dma_entry *entry; - - /* detach and free each entry */ - list_for_each_safe(pos, temp, &list->entries) { - list_del(pos); - entry = list_entry(pos, struct tsi148_dma_entry, list); - kfree(entry); - } - - return 0; -} - -/* - * All 4 location monitors reside at the same base - this is therefore a - * system wide configuration. - * - * This does not enable the LM monitor - that should be done when the first - * callback is attached and disabled when the last callback is removed. - */ -static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, - u32 aspace, u32 cycle) -{ - u32 lm_base_high, lm_base_low, lm_ctl = 0; - int i; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = lm->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&lm->mtx); - - /* If we already have a callback attached, we can't move it! */ - for (i = 0; i < lm->monitors; i++) { - if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Location monitor " - "callback attached, can't reset\n"); - return -EBUSY; - } - } - - switch (aspace) { - case VME_A16: - lm_ctl |= TSI148_LCSR_LMAT_AS_A16; - break; - case VME_A24: - lm_ctl |= TSI148_LCSR_LMAT_AS_A24; - break; - case VME_A32: - lm_ctl |= TSI148_LCSR_LMAT_AS_A32; - break; - case VME_A64: - lm_ctl |= TSI148_LCSR_LMAT_AS_A64; - break; - default: - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Invalid address space\n"); - return -EINVAL; - break; - } - - if (cycle & VME_SUPER) - lm_ctl |= TSI148_LCSR_LMAT_SUPR ; - if (cycle & VME_USER) - lm_ctl |= TSI148_LCSR_LMAT_NPRIV; - if (cycle & VME_PROG) - lm_ctl |= TSI148_LCSR_LMAT_PGM; - if (cycle & VME_DATA) - lm_ctl |= TSI148_LCSR_LMAT_DATA; - - reg_split(lm_base, &lm_base_high, &lm_base_low); - - iowrite32be(lm_base_high, bridge->base + TSI148_LCSR_LMBAU); - iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL); - iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* Get configuration of the callback monitor and return whether it is enabled - * or disabled. - */ -static int tsi148_lm_get(struct vme_lm_resource *lm, - unsigned long long *lm_base, u32 *aspace, u32 *cycle) -{ - u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; - struct tsi148_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU); - lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL); - lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); - - reg_join(lm_base_high, lm_base_low, lm_base); - - if (lm_ctl & TSI148_LCSR_LMAT_EN) - enabled = 1; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) - *aspace |= VME_A16; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) - *aspace |= VME_A24; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) - *aspace |= VME_A32; - - if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) - *aspace |= VME_A64; - - - if (lm_ctl & TSI148_LCSR_LMAT_SUPR) - *cycle |= VME_SUPER; - if (lm_ctl & TSI148_LCSR_LMAT_NPRIV) - *cycle |= VME_USER; - if (lm_ctl & TSI148_LCSR_LMAT_PGM) - *cycle |= VME_PROG; - if (lm_ctl & TSI148_LCSR_LMAT_DATA) - *cycle |= VME_DATA; - - mutex_unlock(&lm->mtx); - - return enabled; -} - -/* - * Attach a callback to a specific location monitor. - * - * Callback will be passed the monitor triggered. - */ -static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, - void (*callback)(int)) -{ - u32 lm_ctl, tmp; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *bridge; - - tsi148_bridge = lm->parent; - - bridge = tsi148_bridge->driver_priv; - - mutex_lock(&lm->mtx); - - /* Ensure that the location monitor is configured - need PGM or DATA */ - lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); - if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Location monitor not properly " - "configured\n"); - return -EINVAL; - } - - /* Check that a callback isn't already attached */ - if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&lm->mtx); - dev_err(tsi148_bridge->parent, "Existing callback attached\n"); - return -EBUSY; - } - - /* Attach callback */ - bridge->lm_callback[monitor] = callback; - - /* Enable Location Monitor interrupt */ - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEN); - tmp |= TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp |= TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - /* Ensure that global Location Monitor Enable set */ - if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) { - lm_ctl |= TSI148_LCSR_LMAT_EN; - iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Detach a callback function forn a specific location monitor. - */ -static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) -{ - u32 lm_en, tmp; - struct tsi148_driver *bridge; - - bridge = lm->parent->driver_priv; - - mutex_lock(&lm->mtx); - - /* Disable Location Monitor and ensure previous interrupts are clear */ - lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN); - lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor]; - iowrite32be(lm_en, bridge->base + TSI148_LCSR_INTEN); - - tmp = ioread32be(bridge->base + TSI148_LCSR_INTEO); - tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor]; - iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); - - iowrite32be(TSI148_LCSR_INTC_LMC[monitor], - bridge->base + TSI148_LCSR_INTC); - - /* Detach callback */ - bridge->lm_callback[monitor] = NULL; - - /* If all location monitors disabled, disable global Location Monitor */ - if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S | - TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) { - tmp = ioread32be(bridge->base + TSI148_LCSR_LMAT); - tmp &= ~TSI148_LCSR_LMAT_EN; - iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT); - } - - mutex_unlock(&lm->mtx); - - return 0; -} - -/* - * Determine Geographical Addressing - */ -static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) -{ - u32 slot = 0; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - if (!geoid) { - slot = ioread32be(bridge->base + TSI148_LCSR_VSTAT); - slot = slot & TSI148_LCSR_VSTAT_GA_M; - } else - slot = geoid; - - return (int)slot; -} - -void *tsi148_alloc_consistent(struct device *parent, size_t size, - dma_addr_t *dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - return pci_alloc_consistent(pdev, size, dma); -} - -void tsi148_free_consistent(struct device *parent, size_t size, void *vaddr, - dma_addr_t dma) -{ - struct pci_dev *pdev; - - /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); - - pci_free_consistent(pdev, size, vaddr, dma); -} - -static int __init tsi148_init(void) -{ - return pci_register_driver(&tsi148_driver); -} - -/* - * Configure CR/CSR space - * - * Access to the CR/CSR can be configured at power-up. The location of the - * CR/CSR registers in the CR/CSR address space is determined by the boards - * Auto-ID or Geographic address. This function ensures that the window is - * enabled at an offset consistent with the boards geopgraphic address. - * - * Each board has a 512kB window, with the highest 4kB being used for the - * boards registers, this means there is a fix length 508kB window which must - * be mapped onto PCI memory. - */ -static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - u32 cbar, crat, vstat; - u32 crcsr_bus_high, crcsr_bus_low; - int retval; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* Allocate mem for CR/CSR image */ - bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &bridge->crcsr_bus); - if (bridge->crcsr_kernel == NULL) { - dev_err(tsi148_bridge->parent, "Failed to allocate memory for " - "CR/CSR image\n"); - return -ENOMEM; - } - - memset(bridge->crcsr_kernel, 0, VME_CRCSR_BUF_SIZE); - - reg_split(bridge->crcsr_bus, &crcsr_bus_high, &crcsr_bus_low); - - iowrite32be(crcsr_bus_high, bridge->base + TSI148_LCSR_CROU); - iowrite32be(crcsr_bus_low, bridge->base + TSI148_LCSR_CROL); - - /* Ensure that the CR/CSR is configured at the correct offset */ - cbar = ioread32be(bridge->base + TSI148_CBAR); - cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3; - - vstat = tsi148_slot_get(tsi148_bridge); - - if (cbar != vstat) { - cbar = vstat; - dev_info(tsi148_bridge->parent, "Setting CR/CSR offset\n"); - iowrite32be(cbar<<3, bridge->base + TSI148_CBAR); - } - dev_info(tsi148_bridge->parent, "CR/CSR Offset: %d\n", cbar); - - crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); - if (crat & TSI148_LCSR_CRAT_EN) { - dev_info(tsi148_bridge->parent, "Enabling CR/CSR space\n"); - iowrite32be(crat | TSI148_LCSR_CRAT_EN, - bridge->base + TSI148_LCSR_CRAT); - } else - dev_info(tsi148_bridge->parent, "CR/CSR already enabled\n"); - - /* If we want flushed, error-checked writes, set up a window - * over the CR/CSR registers. We read from here to safely flush - * through VME writes. - */ - if (err_chk) { - retval = tsi148_master_set(bridge->flush_image, 1, - (vstat * 0x80000), 0x80000, VME_CRCSR, VME_SCT, - VME_D16); - if (retval) - dev_err(tsi148_bridge->parent, "Configuring flush image" - " failed\n"); - } - - return 0; - -} - -static void tsi148_crcsr_exit(struct vme_bridge *tsi148_bridge, - struct pci_dev *pdev) -{ - u32 crat; - struct tsi148_driver *bridge; - - bridge = tsi148_bridge->driver_priv; - - /* Turn off CR/CSR space */ - crat = ioread32be(bridge->base + TSI148_LCSR_CRAT); - iowrite32be(crat & ~TSI148_LCSR_CRAT_EN, - bridge->base + TSI148_LCSR_CRAT); - - /* Free image */ - iowrite32be(0, bridge->base + TSI148_LCSR_CROU); - iowrite32be(0, bridge->base + TSI148_LCSR_CROL); - - pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, bridge->crcsr_kernel, - bridge->crcsr_bus); -} - -static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int retval, i, master_num; - u32 data; - struct list_head *pos = NULL; - struct vme_bridge *tsi148_bridge; - struct tsi148_driver *tsi148_device; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - struct vme_lm_resource *lm; - - /* If we want to support more than one of each bridge, we need to - * dynamically generate this so we get one per device - */ - tsi148_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL); - if (tsi148_bridge == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_struct; - } - - tsi148_device = kzalloc(sizeof(struct tsi148_driver), GFP_KERNEL); - if (tsi148_device == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for device " - "structure\n"); - retval = -ENOMEM; - goto err_driver; - } - - tsi148_bridge->driver_priv = tsi148_device; - - /* Enable the device */ - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "Unable to enable device\n"); - goto err_enable; - } - - /* Map Registers */ - retval = pci_request_regions(pdev, driver_name); - if (retval) { - dev_err(&pdev->dev, "Unable to reserve resources\n"); - goto err_resource; - } - - /* map registers in BAR 0 */ - tsi148_device->base = ioremap_nocache(pci_resource_start(pdev, 0), - 4096); - if (!tsi148_device->base) { - dev_err(&pdev->dev, "Unable to remap CRG region\n"); - retval = -EIO; - goto err_remap; - } - - /* Check to see if the mapping worked out */ - data = ioread32(tsi148_device->base + TSI148_PCFS_ID) & 0x0000FFFF; - if (data != PCI_VENDOR_ID_TUNDRA) { - dev_err(&pdev->dev, "CRG region check failed\n"); - retval = -EIO; - goto err_test; - } - - /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&tsi148_device->dma_queue[0]); - init_waitqueue_head(&tsi148_device->dma_queue[1]); - init_waitqueue_head(&tsi148_device->iack_queue); - mutex_init(&tsi148_device->vme_int); - mutex_init(&tsi148_device->vme_rmw); - - tsi148_bridge->parent = &pdev->dev; - strcpy(tsi148_bridge->name, driver_name); - - /* Setup IRQ */ - retval = tsi148_irq_init(tsi148_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Initialization failed.\n"); - goto err_irq; - } - - /* If we are going to flush writes, we need to read from the VME bus. - * We need to do this safely, thus we read the devices own CR/CSR - * register. To do this we must set up a window in CR/CSR space and - * hence have one less master window resource available. - */ - master_num = TSI148_MAX_MASTER; - if (err_chk) { - master_num--; - - tsi148_device->flush_image = - kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); - if (tsi148_device->flush_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "flush resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - tsi148_device->flush_image->parent = tsi148_bridge; - spin_lock_init(&tsi148_device->flush_image->lock); - tsi148_device->flush_image->locked = 1; - tsi148_device->flush_image->number = master_num; - tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 | - VME_A32 | VME_A64; - tsi148_device->flush_image->cycle_attr = VME_SCT | VME_BLT | - VME_MBLT | VME_2eVME | VME_2eSST | VME_2eSSTB | - VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | - VME_USER | VME_PROG | VME_DATA; - tsi148_device->flush_image->width_attr = VME_D16 | VME_D32; - memset(&tsi148_device->flush_image->bus_resource, 0, - sizeof(struct resource)); - tsi148_device->flush_image->kern_base = NULL; - } - - /* Add master windows to list */ - INIT_LIST_HEAD(&tsi148_bridge->master_resources); - for (i = 0; i < master_num; i++) { - master_image = kmalloc(sizeof(struct vme_master_resource), - GFP_KERNEL); - if (master_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "master resource structure\n"); - retval = -ENOMEM; - goto err_master; - } - master_image->parent = tsi148_bridge; - spin_lock_init(&master_image->lock); - master_image->locked = 0; - master_image->number = i; - master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64; - master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | - VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | - VME_PROG | VME_DATA; - master_image->width_attr = VME_D16 | VME_D32; - memset(&master_image->bus_resource, 0, - sizeof(struct resource)); - master_image->kern_base = NULL; - list_add_tail(&master_image->list, - &tsi148_bridge->master_resources); - } - - /* Add slave windows to list */ - INIT_LIST_HEAD(&tsi148_bridge->slave_resources); - for (i = 0; i < TSI148_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(struct vme_slave_resource), - GFP_KERNEL); - if (slave_image == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "slave resource structure\n"); - retval = -ENOMEM; - goto err_slave; - } - slave_image->parent = tsi148_bridge; - mutex_init(&slave_image->mtx); - slave_image->locked = 0; - slave_image->number = i; - slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | - VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 | - VME_USER3 | VME_USER4; - slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | - VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | - VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | - VME_PROG | VME_DATA; - list_add_tail(&slave_image->list, - &tsi148_bridge->slave_resources); - } - - /* Add dma engines to list */ - INIT_LIST_HEAD(&tsi148_bridge->dma_resources); - for (i = 0; i < TSI148_MAX_DMA; i++) { - dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), - GFP_KERNEL); - if (dma_ctrlr == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "dma resource structure\n"); - retval = -ENOMEM; - goto err_dma; - } - dma_ctrlr->parent = tsi148_bridge; - mutex_init(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - dma_ctrlr->number = i; - dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | - VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | - VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | - VME_DMA_PATTERN_TO_MEM; - INIT_LIST_HEAD(&dma_ctrlr->pending); - INIT_LIST_HEAD(&dma_ctrlr->running); - list_add_tail(&dma_ctrlr->list, - &tsi148_bridge->dma_resources); - } - - /* Add location monitor to list */ - INIT_LIST_HEAD(&tsi148_bridge->lm_resources); - lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); - if (lm == NULL) { - dev_err(&pdev->dev, "Failed to allocate memory for " - "location monitor resource structure\n"); - retval = -ENOMEM; - goto err_lm; - } - lm->parent = tsi148_bridge; - mutex_init(&lm->mtx); - lm->locked = 0; - lm->number = 1; - lm->monitors = 4; - list_add_tail(&lm->list, &tsi148_bridge->lm_resources); - - tsi148_bridge->slave_get = tsi148_slave_get; - tsi148_bridge->slave_set = tsi148_slave_set; - tsi148_bridge->master_get = tsi148_master_get; - tsi148_bridge->master_set = tsi148_master_set; - tsi148_bridge->master_read = tsi148_master_read; - tsi148_bridge->master_write = tsi148_master_write; - tsi148_bridge->master_rmw = tsi148_master_rmw; - tsi148_bridge->dma_list_add = tsi148_dma_list_add; - tsi148_bridge->dma_list_exec = tsi148_dma_list_exec; - tsi148_bridge->dma_list_empty = tsi148_dma_list_empty; - tsi148_bridge->irq_set = tsi148_irq_set; - tsi148_bridge->irq_generate = tsi148_irq_generate; - tsi148_bridge->lm_set = tsi148_lm_set; - tsi148_bridge->lm_get = tsi148_lm_get; - tsi148_bridge->lm_attach = tsi148_lm_attach; - tsi148_bridge->lm_detach = tsi148_lm_detach; - tsi148_bridge->slot_get = tsi148_slot_get; - tsi148_bridge->alloc_consistent = tsi148_alloc_consistent; - tsi148_bridge->free_consistent = tsi148_free_consistent; - - data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); - dev_info(&pdev->dev, "Board is%s the VME system controller\n", - (data & TSI148_LCSR_VSTAT_SCONS) ? "" : " not"); - if (!geoid) - dev_info(&pdev->dev, "VME geographical address is %d\n", - data & TSI148_LCSR_VSTAT_GA_M); - else - dev_info(&pdev->dev, "VME geographical address is set to %d\n", - geoid); - - dev_info(&pdev->dev, "VME Write and flush and error check is %s\n", - err_chk ? "enabled" : "disabled"); - - if (tsi148_crcsr_init(tsi148_bridge, pdev)) { - dev_err(&pdev->dev, "CR/CSR configuration failed.\n"); - goto err_crcsr; - } - - retval = vme_register_bridge(tsi148_bridge); - if (retval != 0) { - dev_err(&pdev->dev, "Chip Registration failed.\n"); - goto err_reg; - } - - pci_set_drvdata(pdev, tsi148_bridge); - - /* Clear VME bus "board fail", and "power-up reset" lines */ - data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); - data &= ~TSI148_LCSR_VSTAT_BRDFL; - data |= TSI148_LCSR_VSTAT_CPURST; - iowrite32be(data, tsi148_device->base + TSI148_LCSR_VSTAT); - - return 0; - -err_reg: - tsi148_crcsr_exit(tsi148_bridge, pdev); -err_crcsr: -err_lm: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->lm_resources) { - lm = list_entry(pos, struct vme_lm_resource, list); - list_del(pos); - kfree(lm); - } -err_dma: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } -err_slave: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } -err_master: - /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - tsi148_irq_exit(tsi148_bridge, pdev); -err_irq: -err_test: - iounmap(tsi148_device->base); -err_remap: - pci_release_regions(pdev); -err_resource: - pci_disable_device(pdev); -err_enable: - kfree(tsi148_device); -err_driver: - kfree(tsi148_bridge); -err_struct: - return retval; - -} - -static void tsi148_remove(struct pci_dev *pdev) -{ - struct list_head *pos = NULL; - struct list_head *tmplist; - struct vme_master_resource *master_image; - struct vme_slave_resource *slave_image; - struct vme_dma_resource *dma_ctrlr; - int i; - struct tsi148_driver *bridge; - struct vme_bridge *tsi148_bridge = pci_get_drvdata(pdev); - - bridge = tsi148_bridge->driver_priv; - - - dev_dbg(&pdev->dev, "Driver is being unloaded.\n"); - - /* - * Shutdown all inbound and outbound windows. - */ - for (i = 0; i < 8; i++) { - iowrite32be(0, bridge->base + TSI148_LCSR_IT[i] + - TSI148_LCSR_OFFSET_ITAT); - iowrite32be(0, bridge->base + TSI148_LCSR_OT[i] + - TSI148_LCSR_OFFSET_OTAT); - } - - /* - * Shutdown Location monitor. - */ - iowrite32be(0, bridge->base + TSI148_LCSR_LMAT); - - /* - * Shutdown CRG map. - */ - iowrite32be(0, bridge->base + TSI148_LCSR_CSRAT); - - /* - * Clear error status. - */ - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_EDPAT); - iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_VEAT); - iowrite32be(0x07000700, bridge->base + TSI148_LCSR_PSTAT); - - /* - * Remove VIRQ interrupt (if any) - */ - if (ioread32be(bridge->base + TSI148_LCSR_VICR) & 0x800) - iowrite32be(0x8000, bridge->base + TSI148_LCSR_VICR); - - /* - * Map all Interrupts to PCI INTA - */ - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1); - iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2); - - tsi148_irq_exit(tsi148_bridge, pdev); - - vme_unregister_bridge(tsi148_bridge); - - tsi148_crcsr_exit(tsi148_bridge, pdev); - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) { - dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); - list_del(pos); - kfree(dma_ctrlr); - } - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) { - slave_image = list_entry(pos, struct vme_slave_resource, list); - list_del(pos); - kfree(slave_image); - } - - /* resources are stored in link list */ - list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) { - master_image = list_entry(pos, struct vme_master_resource, - list); - list_del(pos); - kfree(master_image); - } - - iounmap(bridge->base); - - pci_release_regions(pdev); - - pci_disable_device(pdev); - - kfree(tsi148_bridge->driver_priv); - - kfree(tsi148_bridge); -} - -static void __exit tsi148_exit(void) -{ - pci_unregister_driver(&tsi148_driver); -} - -MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); -module_param(err_chk, bool, 0); - -MODULE_PARM_DESC(geoid, "Override geographical addressing"); -module_param(geoid, int, 0); - -MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); -MODULE_LICENSE("GPL"); - -module_init(tsi148_init); -module_exit(tsi148_exit); diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h deleted file mode 100644 index a3ac2fe..0000000 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * tsi148.h - * - * Support for the Tundra TSI148 VME Bridge chip - * - * Author: Tom Armistead - * Updated and maintained by Ajit Prem - * Copyright 2004 Motorola Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef TSI148_H -#define TSI148_H - -#ifndef PCI_VENDOR_ID_TUNDRA -#define PCI_VENDOR_ID_TUNDRA 0x10e3 -#endif - -#ifndef PCI_DEVICE_ID_TUNDRA_TSI148 -#define PCI_DEVICE_ID_TUNDRA_TSI148 0x148 -#endif - -/* - * Define the number of each that the Tsi148 supports. - */ -#define TSI148_MAX_MASTER 8 /* Max Master Windows */ -#define TSI148_MAX_SLAVE 8 /* Max Slave Windows */ -#define TSI148_MAX_DMA 2 /* Max DMA Controllers */ -#define TSI148_MAX_MAILBOX 4 /* Max Mail Box registers */ -#define TSI148_MAX_SEMAPHORE 8 /* Max Semaphores */ - -/* Structure used to hold driver specific information */ -struct tsi148_driver { - void __iomem *base; /* Base Address of device registers */ - wait_queue_head_t dma_queue[2]; - wait_queue_head_t iack_queue; - void (*lm_callback[4])(int); /* Called in interrupt handler */ - void *crcsr_kernel; - dma_addr_t crcsr_bus; - struct vme_master_resource *flush_image; - struct mutex vme_rmw; /* Only one RMW cycle at a time */ - struct mutex vme_int; /* - * Only one VME interrupt can be - * generated at a time, provide locking - */ -}; - -/* - * Layout of a DMAC Linked-List Descriptor - * - * Note: This structure is accessed via the chip and therefore must be - * correctly laid out - It must also be aligned on 64-bit boundaries. - */ -struct tsi148_dma_descriptor { - u32 dsau; /* Source Address */ - u32 dsal; - u32 ddau; /* Destination Address */ - u32 ddal; - u32 dsat; /* Source attributes */ - u32 ddat; /* Destination attributes */ - u32 dnlau; /* Next link address */ - u32 dnlal; - u32 dcnt; /* Byte count */ - u32 ddbs; /* 2eSST Broadcast select */ -}; - -struct tsi148_dma_entry { - /* - * The descriptor needs to be aligned on a 64-bit boundary, we increase - * the chance of this by putting it first in the structure. - */ - struct tsi148_dma_descriptor descriptor; - struct list_head list; -}; - -/* - * TSI148 ASIC register structure overlays and bit field definitions. - * - * Note: Tsi148 Register Group (CRG) consists of the following - * combination of registers: - * PCFS - PCI Configuration Space Registers - * LCSR - Local Control and Status Registers - * GCSR - Global Control and Status Registers - * CR/CSR - Subset of Configuration ROM / - * Control and Status Registers - */ - - -/* - * Command/Status Registers (CRG + $004) - */ -#define TSI148_PCFS_ID 0x0 -#define TSI148_PCFS_CSR 0x4 -#define TSI148_PCFS_CLASS 0x8 -#define TSI148_PCFS_MISC0 0xC -#define TSI148_PCFS_MBARL 0x10 -#define TSI148_PCFS_MBARU 0x14 - -#define TSI148_PCFS_SUBID 0x28 - -#define TSI148_PCFS_CAPP 0x34 - -#define TSI148_PCFS_MISC1 0x3C - -#define TSI148_PCFS_XCAPP 0x40 -#define TSI148_PCFS_XSTAT 0x44 - -/* - * LCSR definitions - */ - -/* - * Outbound Translations - */ -#define TSI148_LCSR_OT0_OTSAU 0x100 -#define TSI148_LCSR_OT0_OTSAL 0x104 -#define TSI148_LCSR_OT0_OTEAU 0x108 -#define TSI148_LCSR_OT0_OTEAL 0x10C -#define TSI148_LCSR_OT0_OTOFU 0x110 -#define TSI148_LCSR_OT0_OTOFL 0x114 -#define TSI148_LCSR_OT0_OTBS 0x118 -#define TSI148_LCSR_OT0_OTAT 0x11C - -#define TSI148_LCSR_OT1_OTSAU 0x120 -#define TSI148_LCSR_OT1_OTSAL 0x124 -#define TSI148_LCSR_OT1_OTEAU 0x128 -#define TSI148_LCSR_OT1_OTEAL 0x12C -#define TSI148_LCSR_OT1_OTOFU 0x130 -#define TSI148_LCSR_OT1_OTOFL 0x134 -#define TSI148_LCSR_OT1_OTBS 0x138 -#define TSI148_LCSR_OT1_OTAT 0x13C - -#define TSI148_LCSR_OT2_OTSAU 0x140 -#define TSI148_LCSR_OT2_OTSAL 0x144 -#define TSI148_LCSR_OT2_OTEAU 0x148 -#define TSI148_LCSR_OT2_OTEAL 0x14C -#define TSI148_LCSR_OT2_OTOFU 0x150 -#define TSI148_LCSR_OT2_OTOFL 0x154 -#define TSI148_LCSR_OT2_OTBS 0x158 -#define TSI148_LCSR_OT2_OTAT 0x15C - -#define TSI148_LCSR_OT3_OTSAU 0x160 -#define TSI148_LCSR_OT3_OTSAL 0x164 -#define TSI148_LCSR_OT3_OTEAU 0x168 -#define TSI148_LCSR_OT3_OTEAL 0x16C -#define TSI148_LCSR_OT3_OTOFU 0x170 -#define TSI148_LCSR_OT3_OTOFL 0x174 -#define TSI148_LCSR_OT3_OTBS 0x178 -#define TSI148_LCSR_OT3_OTAT 0x17C - -#define TSI148_LCSR_OT4_OTSAU 0x180 -#define TSI148_LCSR_OT4_OTSAL 0x184 -#define TSI148_LCSR_OT4_OTEAU 0x188 -#define TSI148_LCSR_OT4_OTEAL 0x18C -#define TSI148_LCSR_OT4_OTOFU 0x190 -#define TSI148_LCSR_OT4_OTOFL 0x194 -#define TSI148_LCSR_OT4_OTBS 0x198 -#define TSI148_LCSR_OT4_OTAT 0x19C - -#define TSI148_LCSR_OT5_OTSAU 0x1A0 -#define TSI148_LCSR_OT5_OTSAL 0x1A4 -#define TSI148_LCSR_OT5_OTEAU 0x1A8 -#define TSI148_LCSR_OT5_OTEAL 0x1AC -#define TSI148_LCSR_OT5_OTOFU 0x1B0 -#define TSI148_LCSR_OT5_OTOFL 0x1B4 -#define TSI148_LCSR_OT5_OTBS 0x1B8 -#define TSI148_LCSR_OT5_OTAT 0x1BC - -#define TSI148_LCSR_OT6_OTSAU 0x1C0 -#define TSI148_LCSR_OT6_OTSAL 0x1C4 -#define TSI148_LCSR_OT6_OTEAU 0x1C8 -#define TSI148_LCSR_OT6_OTEAL 0x1CC -#define TSI148_LCSR_OT6_OTOFU 0x1D0 -#define TSI148_LCSR_OT6_OTOFL 0x1D4 -#define TSI148_LCSR_OT6_OTBS 0x1D8 -#define TSI148_LCSR_OT6_OTAT 0x1DC - -#define TSI148_LCSR_OT7_OTSAU 0x1E0 -#define TSI148_LCSR_OT7_OTSAL 0x1E4 -#define TSI148_LCSR_OT7_OTEAU 0x1E8 -#define TSI148_LCSR_OT7_OTEAL 0x1EC -#define TSI148_LCSR_OT7_OTOFU 0x1F0 -#define TSI148_LCSR_OT7_OTOFL 0x1F4 -#define TSI148_LCSR_OT7_OTBS 0x1F8 -#define TSI148_LCSR_OT7_OTAT 0x1FC - -#define TSI148_LCSR_OT0 0x100 -#define TSI148_LCSR_OT1 0x120 -#define TSI148_LCSR_OT2 0x140 -#define TSI148_LCSR_OT3 0x160 -#define TSI148_LCSR_OT4 0x180 -#define TSI148_LCSR_OT5 0x1A0 -#define TSI148_LCSR_OT6 0x1C0 -#define TSI148_LCSR_OT7 0x1E0 - -static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1, - TSI148_LCSR_OT2, TSI148_LCSR_OT3, - TSI148_LCSR_OT4, TSI148_LCSR_OT5, - TSI148_LCSR_OT6, TSI148_LCSR_OT7 }; - -#define TSI148_LCSR_OFFSET_OTSAU 0x0 -#define TSI148_LCSR_OFFSET_OTSAL 0x4 -#define TSI148_LCSR_OFFSET_OTEAU 0x8 -#define TSI148_LCSR_OFFSET_OTEAL 0xC -#define TSI148_LCSR_OFFSET_OTOFU 0x10 -#define TSI148_LCSR_OFFSET_OTOFL 0x14 -#define TSI148_LCSR_OFFSET_OTBS 0x18 -#define TSI148_LCSR_OFFSET_OTAT 0x1C - -/* - * VMEbus interrupt ack - * offset 200 - */ -#define TSI148_LCSR_VIACK1 0x204 -#define TSI148_LCSR_VIACK2 0x208 -#define TSI148_LCSR_VIACK3 0x20C -#define TSI148_LCSR_VIACK4 0x210 -#define TSI148_LCSR_VIACK5 0x214 -#define TSI148_LCSR_VIACK6 0x218 -#define TSI148_LCSR_VIACK7 0x21C - -static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1, - TSI148_LCSR_VIACK2, TSI148_LCSR_VIACK3, - TSI148_LCSR_VIACK4, TSI148_LCSR_VIACK5, - TSI148_LCSR_VIACK6, TSI148_LCSR_VIACK7 }; - -/* - * RMW - * offset 220 - */ -#define TSI148_LCSR_RMWAU 0x220 -#define TSI148_LCSR_RMWAL 0x224 -#define TSI148_LCSR_RMWEN 0x228 -#define TSI148_LCSR_RMWC 0x22C -#define TSI148_LCSR_RMWS 0x230 - -/* - * VMEbus control - * offset 234 - */ -#define TSI148_LCSR_VMCTRL 0x234 -#define TSI148_LCSR_VCTRL 0x238 -#define TSI148_LCSR_VSTAT 0x23C - -/* - * PCI status - * offset 240 - */ -#define TSI148_LCSR_PSTAT 0x240 - -/* - * VME filter. - * offset 250 - */ -#define TSI148_LCSR_VMEFL 0x250 - - /* - * VME exception. - * offset 260 - */ -#define TSI148_LCSR_VEAU 0x260 -#define TSI148_LCSR_VEAL 0x264 -#define TSI148_LCSR_VEAT 0x268 - - /* - * PCI error - * offset 270 - */ -#define TSI148_LCSR_EDPAU 0x270 -#define TSI148_LCSR_EDPAL 0x274 -#define TSI148_LCSR_EDPXA 0x278 -#define TSI148_LCSR_EDPXS 0x27C -#define TSI148_LCSR_EDPAT 0x280 - - /* - * Inbound Translations - * offset 300 - */ -#define TSI148_LCSR_IT0_ITSAU 0x300 -#define TSI148_LCSR_IT0_ITSAL 0x304 -#define TSI148_LCSR_IT0_ITEAU 0x308 -#define TSI148_LCSR_IT0_ITEAL 0x30C -#define TSI148_LCSR_IT0_ITOFU 0x310 -#define TSI148_LCSR_IT0_ITOFL 0x314 -#define TSI148_LCSR_IT0_ITAT 0x318 - -#define TSI148_LCSR_IT1_ITSAU 0x320 -#define TSI148_LCSR_IT1_ITSAL 0x324 -#define TSI148_LCSR_IT1_ITEAU 0x328 -#define TSI148_LCSR_IT1_ITEAL 0x32C -#define TSI148_LCSR_IT1_ITOFU 0x330 -#define TSI148_LCSR_IT1_ITOFL 0x334 -#define TSI148_LCSR_IT1_ITAT 0x338 - -#define TSI148_LCSR_IT2_ITSAU 0x340 -#define TSI148_LCSR_IT2_ITSAL 0x344 -#define TSI148_LCSR_IT2_ITEAU 0x348 -#define TSI148_LCSR_IT2_ITEAL 0x34C -#define TSI148_LCSR_IT2_ITOFU 0x350 -#define TSI148_LCSR_IT2_ITOFL 0x354 -#define TSI148_LCSR_IT2_ITAT 0x358 - -#define TSI148_LCSR_IT3_ITSAU 0x360 -#define TSI148_LCSR_IT3_ITSAL 0x364 -#define TSI148_LCSR_IT3_ITEAU 0x368 -#define TSI148_LCSR_IT3_ITEAL 0x36C -#define TSI148_LCSR_IT3_ITOFU 0x370 -#define TSI148_LCSR_IT3_ITOFL 0x374 -#define TSI148_LCSR_IT3_ITAT 0x378 - -#define TSI148_LCSR_IT4_ITSAU 0x380 -#define TSI148_LCSR_IT4_ITSAL 0x384 -#define TSI148_LCSR_IT4_ITEAU 0x388 -#define TSI148_LCSR_IT4_ITEAL 0x38C -#define TSI148_LCSR_IT4_ITOFU 0x390 -#define TSI148_LCSR_IT4_ITOFL 0x394 -#define TSI148_LCSR_IT4_ITAT 0x398 - -#define TSI148_LCSR_IT5_ITSAU 0x3A0 -#define TSI148_LCSR_IT5_ITSAL 0x3A4 -#define TSI148_LCSR_IT5_ITEAU 0x3A8 -#define TSI148_LCSR_IT5_ITEAL 0x3AC -#define TSI148_LCSR_IT5_ITOFU 0x3B0 -#define TSI148_LCSR_IT5_ITOFL 0x3B4 -#define TSI148_LCSR_IT5_ITAT 0x3B8 - -#define TSI148_LCSR_IT6_ITSAU 0x3C0 -#define TSI148_LCSR_IT6_ITSAL 0x3C4 -#define TSI148_LCSR_IT6_ITEAU 0x3C8 -#define TSI148_LCSR_IT6_ITEAL 0x3CC -#define TSI148_LCSR_IT6_ITOFU 0x3D0 -#define TSI148_LCSR_IT6_ITOFL 0x3D4 -#define TSI148_LCSR_IT6_ITAT 0x3D8 - -#define TSI148_LCSR_IT7_ITSAU 0x3E0 -#define TSI148_LCSR_IT7_ITSAL 0x3E4 -#define TSI148_LCSR_IT7_ITEAU 0x3E8 -#define TSI148_LCSR_IT7_ITEAL 0x3EC -#define TSI148_LCSR_IT7_ITOFU 0x3F0 -#define TSI148_LCSR_IT7_ITOFL 0x3F4 -#define TSI148_LCSR_IT7_ITAT 0x3F8 - - -#define TSI148_LCSR_IT0 0x300 -#define TSI148_LCSR_IT1 0x320 -#define TSI148_LCSR_IT2 0x340 -#define TSI148_LCSR_IT3 0x360 -#define TSI148_LCSR_IT4 0x380 -#define TSI148_LCSR_IT5 0x3A0 -#define TSI148_LCSR_IT6 0x3C0 -#define TSI148_LCSR_IT7 0x3E0 - -static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1, - TSI148_LCSR_IT2, TSI148_LCSR_IT3, - TSI148_LCSR_IT4, TSI148_LCSR_IT5, - TSI148_LCSR_IT6, TSI148_LCSR_IT7 }; - -#define TSI148_LCSR_OFFSET_ITSAU 0x0 -#define TSI148_LCSR_OFFSET_ITSAL 0x4 -#define TSI148_LCSR_OFFSET_ITEAU 0x8 -#define TSI148_LCSR_OFFSET_ITEAL 0xC -#define TSI148_LCSR_OFFSET_ITOFU 0x10 -#define TSI148_LCSR_OFFSET_ITOFL 0x14 -#define TSI148_LCSR_OFFSET_ITAT 0x18 - - /* - * Inbound Translation GCSR - * offset 400 - */ -#define TSI148_LCSR_GBAU 0x400 -#define TSI148_LCSR_GBAL 0x404 -#define TSI148_LCSR_GCSRAT 0x408 - - /* - * Inbound Translation CRG - * offset 40C - */ -#define TSI148_LCSR_CBAU 0x40C -#define TSI148_LCSR_CBAL 0x410 -#define TSI148_LCSR_CSRAT 0x414 - - /* - * Inbound Translation CR/CSR - * CRG - * offset 418 - */ -#define TSI148_LCSR_CROU 0x418 -#define TSI148_LCSR_CROL 0x41C -#define TSI148_LCSR_CRAT 0x420 - - /* - * Inbound Translation Location Monitor - * offset 424 - */ -#define TSI148_LCSR_LMBAU 0x424 -#define TSI148_LCSR_LMBAL 0x428 -#define TSI148_LCSR_LMAT 0x42C - - /* - * VMEbus Interrupt Control. - * offset 430 - */ -#define TSI148_LCSR_BCU 0x430 -#define TSI148_LCSR_BCL 0x434 -#define TSI148_LCSR_BPGTR 0x438 -#define TSI148_LCSR_BPCTR 0x43C -#define TSI148_LCSR_VICR 0x440 - - /* - * Local Bus Interrupt Control. - * offset 448 - */ -#define TSI148_LCSR_INTEN 0x448 -#define TSI148_LCSR_INTEO 0x44C -#define TSI148_LCSR_INTS 0x450 -#define TSI148_LCSR_INTC 0x454 -#define TSI148_LCSR_INTM1 0x458 -#define TSI148_LCSR_INTM2 0x45C - - /* - * DMA Controllers - * offset 500 - */ -#define TSI148_LCSR_DCTL0 0x500 -#define TSI148_LCSR_DSTA0 0x504 -#define TSI148_LCSR_DCSAU0 0x508 -#define TSI148_LCSR_DCSAL0 0x50C -#define TSI148_LCSR_DCDAU0 0x510 -#define TSI148_LCSR_DCDAL0 0x514 -#define TSI148_LCSR_DCLAU0 0x518 -#define TSI148_LCSR_DCLAL0 0x51C -#define TSI148_LCSR_DSAU0 0x520 -#define TSI148_LCSR_DSAL0 0x524 -#define TSI148_LCSR_DDAU0 0x528 -#define TSI148_LCSR_DDAL0 0x52C -#define TSI148_LCSR_DSAT0 0x530 -#define TSI148_LCSR_DDAT0 0x534 -#define TSI148_LCSR_DNLAU0 0x538 -#define TSI148_LCSR_DNLAL0 0x53C -#define TSI148_LCSR_DCNT0 0x540 -#define TSI148_LCSR_DDBS0 0x544 - -#define TSI148_LCSR_DCTL1 0x580 -#define TSI148_LCSR_DSTA1 0x584 -#define TSI148_LCSR_DCSAU1 0x588 -#define TSI148_LCSR_DCSAL1 0x58C -#define TSI148_LCSR_DCDAU1 0x590 -#define TSI148_LCSR_DCDAL1 0x594 -#define TSI148_LCSR_DCLAU1 0x598 -#define TSI148_LCSR_DCLAL1 0x59C -#define TSI148_LCSR_DSAU1 0x5A0 -#define TSI148_LCSR_DSAL1 0x5A4 -#define TSI148_LCSR_DDAU1 0x5A8 -#define TSI148_LCSR_DDAL1 0x5AC -#define TSI148_LCSR_DSAT1 0x5B0 -#define TSI148_LCSR_DDAT1 0x5B4 -#define TSI148_LCSR_DNLAU1 0x5B8 -#define TSI148_LCSR_DNLAL1 0x5BC -#define TSI148_LCSR_DCNT1 0x5C0 -#define TSI148_LCSR_DDBS1 0x5C4 - -#define TSI148_LCSR_DMA0 0x500 -#define TSI148_LCSR_DMA1 0x580 - - -static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0, - TSI148_LCSR_DMA1 }; - -#define TSI148_LCSR_OFFSET_DCTL 0x0 -#define TSI148_LCSR_OFFSET_DSTA 0x4 -#define TSI148_LCSR_OFFSET_DCSAU 0x8 -#define TSI148_LCSR_OFFSET_DCSAL 0xC -#define TSI148_LCSR_OFFSET_DCDAU 0x10 -#define TSI148_LCSR_OFFSET_DCDAL 0x14 -#define TSI148_LCSR_OFFSET_DCLAU 0x18 -#define TSI148_LCSR_OFFSET_DCLAL 0x1C -#define TSI148_LCSR_OFFSET_DSAU 0x20 -#define TSI148_LCSR_OFFSET_DSAL 0x24 -#define TSI148_LCSR_OFFSET_DDAU 0x28 -#define TSI148_LCSR_OFFSET_DDAL 0x2C -#define TSI148_LCSR_OFFSET_DSAT 0x30 -#define TSI148_LCSR_OFFSET_DDAT 0x34 -#define TSI148_LCSR_OFFSET_DNLAU 0x38 -#define TSI148_LCSR_OFFSET_DNLAL 0x3C -#define TSI148_LCSR_OFFSET_DCNT 0x40 -#define TSI148_LCSR_OFFSET_DDBS 0x44 - - /* - * GCSR Register Group - */ - - /* - * GCSR CRG - * offset 00 600 - DEVI/VENI - * offset 04 604 - CTRL/GA/REVID - * offset 08 608 - Semaphore3/2/1/0 - * offset 0C 60C - Seamphore7/6/5/4 - */ -#define TSI148_GCSR_ID 0x600 -#define TSI148_GCSR_CSR 0x604 -#define TSI148_GCSR_SEMA0 0x608 -#define TSI148_GCSR_SEMA1 0x60C - - /* - * Mail Box - * GCSR CRG - * offset 10 610 - Mailbox0 - */ -#define TSI148_GCSR_MBOX0 0x610 -#define TSI148_GCSR_MBOX1 0x614 -#define TSI148_GCSR_MBOX2 0x618 -#define TSI148_GCSR_MBOX3 0x61C - -static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0, - TSI148_GCSR_MBOX1, - TSI148_GCSR_MBOX2, - TSI148_GCSR_MBOX3 }; - - /* - * CR/CSR - */ - - /* - * CR/CSR CRG - * offset 7FFF4 FF4 - CSRBCR - * offset 7FFF8 FF8 - CSRBSR - * offset 7FFFC FFC - CBAR - */ -#define TSI148_CSRBCR 0xFF4 -#define TSI148_CSRBSR 0xFF8 -#define TSI148_CBAR 0xFFC - - - - - /* - * TSI148 Register Bit Definitions - */ - - /* - * PFCS Register Set - */ -#define TSI148_PCFS_CMMD_SERR (1<<8) /* SERR_L out pin ssys err */ -#define TSI148_PCFS_CMMD_PERR (1<<6) /* PERR_L out pin parity */ -#define TSI148_PCFS_CMMD_MSTR (1<<2) /* PCI bus master */ -#define TSI148_PCFS_CMMD_MEMSP (1<<1) /* PCI mem space access */ -#define TSI148_PCFS_CMMD_IOSP (1<<0) /* PCI I/O space enable */ - -#define TSI148_PCFS_STAT_RCPVE (1<<15) /* Detected Parity Error */ -#define TSI148_PCFS_STAT_SIGSE (1<<14) /* Signalled System Error */ -#define TSI148_PCFS_STAT_RCVMA (1<<13) /* Received Master Abort */ -#define TSI148_PCFS_STAT_RCVTA (1<<12) /* Received Target Abort */ -#define TSI148_PCFS_STAT_SIGTA (1<<11) /* Signalled Target Abort */ -#define TSI148_PCFS_STAT_SELTIM (3<<9) /* DELSEL Timing */ -#define TSI148_PCFS_STAT_DPAR (1<<8) /* Data Parity Err Reported */ -#define TSI148_PCFS_STAT_FAST (1<<7) /* Fast back-to-back Cap */ -#define TSI148_PCFS_STAT_P66M (1<<5) /* 66 MHz Capable */ -#define TSI148_PCFS_STAT_CAPL (1<<4) /* Capab List - address $34 */ - -/* - * Revision ID/Class Code Registers (CRG +$008) - */ -#define TSI148_PCFS_CLAS_M (0xFF<<24) /* Class ID */ -#define TSI148_PCFS_SUBCLAS_M (0xFF<<16) /* Sub-Class ID */ -#define TSI148_PCFS_PROGIF_M (0xFF<<8) /* Sub-Class ID */ -#define TSI148_PCFS_REVID_M (0xFF<<0) /* Rev ID */ - -/* - * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C) - */ -#define TSI148_PCFS_HEAD_M (0xFF<<16) /* Master Lat Timer */ -#define TSI148_PCFS_MLAT_M (0xFF<<8) /* Master Lat Timer */ -#define TSI148_PCFS_CLSZ_M (0xFF<<0) /* Cache Line Size */ - -/* - * Memory Base Address Lower Reg (CRG + $010) - */ -#define TSI148_PCFS_MBARL_BASEL_M (0xFFFFF<<12) /* Base Addr Lower Mask */ -#define TSI148_PCFS_MBARL_PRE (1<<3) /* Prefetch */ -#define TSI148_PCFS_MBARL_MTYPE_M (3<<1) /* Memory Type Mask */ -#define TSI148_PCFS_MBARL_IOMEM (1<<0) /* I/O Space Indicator */ - -/* - * Message Signaled Interrupt Capabilities Register (CRG + $040) - */ -#define TSI148_PCFS_MSICAP_64BAC (1<<7) /* 64-bit Address Capable */ -#define TSI148_PCFS_MSICAP_MME_M (7<<4) /* Multiple Msg Enable Mask */ -#define TSI148_PCFS_MSICAP_MMC_M (7<<1) /* Multiple Msg Capable Mask */ -#define TSI148_PCFS_MSICAP_MSIEN (1<<0) /* Msg signaled INT Enable */ - -/* - * Message Address Lower Register (CRG +$044) - */ -#define TSI148_PCFS_MSIAL_M (0x3FFFFFFF<<2) /* Mask */ - -/* - * Message Data Register (CRG + 4C) - */ -#define TSI148_PCFS_MSIMD_M (0xFFFF<<0) /* Mask */ - -/* - * PCI-X Capabilities Register (CRG + $050) - */ -#define TSI148_PCFS_PCIXCAP_MOST_M (7<<4) /* Max outstanding Split Tran */ -#define TSI148_PCFS_PCIXCAP_MMRBC_M (3<<2) /* Max Mem Read byte cnt */ -#define TSI148_PCFS_PCIXCAP_ERO (1<<1) /* Enable Relaxed Ordering */ -#define TSI148_PCFS_PCIXCAP_DPERE (1<<0) /* Data Parity Recover Enable */ - -/* - * PCI-X Status Register (CRG +$054) - */ -#define TSI148_PCFS_PCIXSTAT_RSCEM (1<<29) /* Received Split Comp Error */ -#define TSI148_PCFS_PCIXSTAT_DMCRS_M (7<<26) /* max Cumulative Read Size */ -#define TSI148_PCFS_PCIXSTAT_DMOST_M (7<<23) /* max outstanding Split Trans - */ -#define TSI148_PCFS_PCIXSTAT_DMMRC_M (3<<21) /* max mem read byte count */ -#define TSI148_PCFS_PCIXSTAT_DC (1<<20) /* Device Complexity */ -#define TSI148_PCFS_PCIXSTAT_USC (1<<19) /* Unexpected Split comp */ -#define TSI148_PCFS_PCIXSTAT_SCD (1<<18) /* Split completion discard */ -#define TSI148_PCFS_PCIXSTAT_133C (1<<17) /* 133MHz capable */ -#define TSI148_PCFS_PCIXSTAT_64D (1<<16) /* 64 bit device */ -#define TSI148_PCFS_PCIXSTAT_BN_M (0xFF<<8) /* Bus number */ -#define TSI148_PCFS_PCIXSTAT_DN_M (0x1F<<3) /* Device number */ -#define TSI148_PCFS_PCIXSTAT_FN_M (7<<0) /* Function Number */ - -/* - * LCSR Registers - */ - -/* - * Outbound Translation Starting Address Lower - */ -#define TSI148_LCSR_OTSAL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation Ending Address Lower - */ -#define TSI148_LCSR_OTEAL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation Offset Lower - */ -#define TSI148_LCSR_OTOFFL_M (0xFFFF<<16) /* Mask */ - -/* - * Outbound Translation 2eSST Broadcast Select - */ -#define TSI148_LCSR_OTBS_M (0xFFFFF<<0) /* Mask */ - -/* - * Outbound Translation Attribute - */ -#define TSI148_LCSR_OTAT_EN (1<<31) /* Window Enable */ -#define TSI148_LCSR_OTAT_MRPFD (1<<18) /* Prefetch Disable */ - -#define TSI148_LCSR_OTAT_PFS_M (3<<16) /* Prefetch Size Mask */ -#define TSI148_LCSR_OTAT_PFS_2 (0<<16) /* 2 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_4 (1<<16) /* 4 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_8 (2<<16) /* 8 Cache Lines P Size */ -#define TSI148_LCSR_OTAT_PFS_16 (3<<16) /* 16 Cache Lines P Size */ - -#define TSI148_LCSR_OTAT_2eSSTM_M (7<<11) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_OTAT_2eSSTM_160 (0<<11) /* 160MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_2eSSTM_267 (1<<11) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_OTAT_2eSSTM_320 (2<<11) /* 320MB/s 2eSST Xfer Rate */ - -#define TSI148_LCSR_OTAT_TM_M (7<<8) /* Xfer Protocol Mask */ -#define TSI148_LCSR_OTAT_TM_SCT (0<<8) /* SCT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_BLT (1<<8) /* BLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_MBLT (2<<8) /* MBLT Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eVME (3<<8) /* 2eVME Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSST (4<<8) /* 2eSST Xfer Protocol */ -#define TSI148_LCSR_OTAT_TM_2eSSTB (5<<8) /* 2eSST Bcast Xfer Protocol */ - -#define TSI148_LCSR_OTAT_DBW_M (3<<6) /* Max Data Width */ -#define TSI148_LCSR_OTAT_DBW_16 (0<<6) /* 16-bit Data Width */ -#define TSI148_LCSR_OTAT_DBW_32 (1<<6) /* 32-bit Data Width */ - -#define TSI148_LCSR_OTAT_SUP (1<<5) /* Supervisory Access */ -#define TSI148_LCSR_OTAT_PGM (1<<4) /* Program Access */ - -#define TSI148_LCSR_OTAT_AMODE_M (0xf<<0) /* Address Mode Mask */ -#define TSI148_LCSR_OTAT_AMODE_A16 (0<<0) /* A16 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A24 (1<<0) /* A24 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A32 (2<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_A64 (4<<0) /* A32 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_CRCSR (5<<0) /* CR/CSR Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER1 (8<<0) /* User1 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER2 (9<<0) /* User2 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER3 (10<<0) /* User3 Address Space */ -#define TSI148_LCSR_OTAT_AMODE_USER4 (11<<0) /* User4 Address Space */ - -/* - * VME Master Control Register CRG+$234 - */ -#define TSI148_LCSR_VMCTRL_VSA (1<<27) /* VMEbus Stop Ack */ -#define TSI148_LCSR_VMCTRL_VS (1<<26) /* VMEbus Stop */ -#define TSI148_LCSR_VMCTRL_DHB (1<<25) /* Device Has Bus */ -#define TSI148_LCSR_VMCTRL_DWB (1<<24) /* Device Wants Bus */ - -#define TSI148_LCSR_VMCTRL_RMWEN (1<<20) /* RMW Enable */ - -#define TSI148_LCSR_VMCTRL_ATO_M (7<<16) /* Master Access Time-out Mask - */ -#define TSI148_LCSR_VMCTRL_ATO_32 (0<<16) /* 32 us */ -#define TSI148_LCSR_VMCTRL_ATO_128 (1<<16) /* 128 us */ -#define TSI148_LCSR_VMCTRL_ATO_512 (2<<16) /* 512 us */ -#define TSI148_LCSR_VMCTRL_ATO_2M (3<<16) /* 2 ms */ -#define TSI148_LCSR_VMCTRL_ATO_8M (4<<16) /* 8 ms */ -#define TSI148_LCSR_VMCTRL_ATO_32M (5<<16) /* 32 ms */ -#define TSI148_LCSR_VMCTRL_ATO_128M (6<<16) /* 128 ms */ -#define TSI148_LCSR_VMCTRL_ATO_DIS (7<<16) /* Disabled */ - -#define TSI148_LCSR_VMCTRL_VTOFF_M (7<<12) /* VMEbus Master Time off */ -#define TSI148_LCSR_VMCTRL_VTOFF_0 (0<<12) /* 0us */ -#define TSI148_LCSR_VMCTRL_VTOFF_1 (1<<12) /* 1us */ -#define TSI148_LCSR_VMCTRL_VTOFF_2 (2<<12) /* 2us */ -#define TSI148_LCSR_VMCTRL_VTOFF_4 (3<<12) /* 4us */ -#define TSI148_LCSR_VMCTRL_VTOFF_8 (4<<12) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTOFF_16 (5<<12) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTOFF_32 (6<<12) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTOFF_64 (7<<12) /* 64us */ - -#define TSI148_LCSR_VMCTRL_VTON_M (7<<8) /* VMEbus Master Time On */ -#define TSI148_LCSR_VMCTRL_VTON_4 (0<<8) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTON_8 (1<<8) /* 8us */ -#define TSI148_LCSR_VMCTRL_VTON_16 (2<<8) /* 16us */ -#define TSI148_LCSR_VMCTRL_VTON_32 (3<<8) /* 32us */ -#define TSI148_LCSR_VMCTRL_VTON_64 (4<<8) /* 64us */ -#define TSI148_LCSR_VMCTRL_VTON_128 (5<<8) /* 128us */ -#define TSI148_LCSR_VMCTRL_VTON_256 (6<<8) /* 256us */ -#define TSI148_LCSR_VMCTRL_VTON_512 (7<<8) /* 512us */ - -#define TSI148_LCSR_VMCTRL_VREL_M (3<<3) /* VMEbus Master Rel Mode Mask - */ -#define TSI148_LCSR_VMCTRL_VREL_T_D (0<<3) /* Time on or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_R_D (1<<3) /* Time on and REQ or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_B_D (2<<3) /* Time on and BCLR or Done */ -#define TSI148_LCSR_VMCTRL_VREL_T_D_R (3<<3) /* Time on or Done and REQ */ - -#define TSI148_LCSR_VMCTRL_VFAIR (1<<2) /* VMEbus Master Fair Mode */ -#define TSI148_LCSR_VMCTRL_VREQL_M (3<<0) /* VMEbus Master Req Level Mask - */ - -/* - * VMEbus Control Register CRG+$238 - */ -#define TSI148_LCSR_VCTRL_LRE (1<<31) /* Late Retry Enable */ - -#define TSI148_LCSR_VCTRL_DLT_M (0xF<<24) /* Deadlock Timer */ -#define TSI148_LCSR_VCTRL_DLT_OFF (0<<24) /* Deadlock Timer Off */ -#define TSI148_LCSR_VCTRL_DLT_16 (1<<24) /* 16 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32 (2<<24) /* 32 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_64 (3<<24) /* 64 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_128 (4<<24) /* 128 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_256 (5<<24) /* 256 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_512 (6<<24) /* 512 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_1024 (7<<24) /* 1024 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_2048 (8<<24) /* 2048 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_4096 (9<<24) /* 4096 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_8192 (0xA<<24) /* 8192 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_16384 (0xB<<24) /* 16384 VCLKS */ -#define TSI148_LCSR_VCTRL_DLT_32768 (0xC<<24) /* 32768 VCLKS */ - -#define TSI148_LCSR_VCTRL_NERBB (1<<20) /* No Early Release of Bus Busy - */ - -#define TSI148_LCSR_VCTRL_SRESET (1<<17) /* System Reset */ -#define TSI148_LCSR_VCTRL_LRESET (1<<16) /* Local Reset */ - -#define TSI148_LCSR_VCTRL_SFAILAI (1<<15) /* SYSFAIL Auto Slot ID */ -#define TSI148_LCSR_VCTRL_BID_M (0x1F<<8) /* Broadcast ID Mask */ - -#define TSI148_LCSR_VCTRL_ATOEN (1<<7) /* Arbiter Time-out Enable */ -#define TSI148_LCSR_VCTRL_ROBIN (1<<6) /* VMEbus Round Robin */ - -#define TSI148_LCSR_VCTRL_GTO_M (7<<0) /* VMEbus Global Time-out Mask - */ -#define TSI148_LCSR_VCTRL_GTO_8 (0<<0) /* 8 us */ -#define TSI148_LCSR_VCTRL_GTO_16 (1<<0) /* 16 us */ -#define TSI148_LCSR_VCTRL_GTO_32 (2<<0) /* 32 us */ -#define TSI148_LCSR_VCTRL_GTO_64 (3<<0) /* 64 us */ -#define TSI148_LCSR_VCTRL_GTO_128 (4<<0) /* 128 us */ -#define TSI148_LCSR_VCTRL_GTO_256 (5<<0) /* 256 us */ -#define TSI148_LCSR_VCTRL_GTO_512 (6<<0) /* 512 us */ -#define TSI148_LCSR_VCTRL_GTO_DIS (7<<0) /* Disabled */ - -/* - * VMEbus Status Register CRG + $23C - */ -#define TSI148_LCSR_VSTAT_CPURST (1<<15) /* Clear power up reset */ -#define TSI148_LCSR_VSTAT_BRDFL (1<<14) /* Board fail */ -#define TSI148_LCSR_VSTAT_PURSTS (1<<12) /* Power up reset status */ -#define TSI148_LCSR_VSTAT_BDFAILS (1<<11) /* Board Fail Status */ -#define TSI148_LCSR_VSTAT_SYSFAILS (1<<10) /* System Fail Status */ -#define TSI148_LCSR_VSTAT_ACFAILS (1<<9) /* AC fail status */ -#define TSI148_LCSR_VSTAT_SCONS (1<<8) /* System Cont Status */ -#define TSI148_LCSR_VSTAT_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_LCSR_VSTAT_GA_M (0x1F<<0) /* Geographic Addr Mask */ - -/* - * PCI Configuration Status Register CRG+$240 - */ -#define TSI148_LCSR_PSTAT_REQ64S (1<<6) /* Request 64 status set */ -#define TSI148_LCSR_PSTAT_M66ENS (1<<5) /* M66ENS 66Mhz enable */ -#define TSI148_LCSR_PSTAT_FRAMES (1<<4) /* Frame Status */ -#define TSI148_LCSR_PSTAT_IRDYS (1<<3) /* IRDY status */ -#define TSI148_LCSR_PSTAT_DEVSELS (1<<2) /* DEVL status */ -#define TSI148_LCSR_PSTAT_STOPS (1<<1) /* STOP status */ -#define TSI148_LCSR_PSTAT_TRDYS (1<<0) /* TRDY status */ - -/* - * VMEbus Exception Attributes Register CRG + $268 - */ -#define TSI148_LCSR_VEAT_VES (1<<31) /* Status */ -#define TSI148_LCSR_VEAT_VEOF (1<<30) /* Overflow */ -#define TSI148_LCSR_VEAT_VESCL (1<<29) /* Status Clear */ -#define TSI148_LCSR_VEAT_2EOT (1<<21) /* 2e Odd Termination */ -#define TSI148_LCSR_VEAT_2EST (1<<20) /* 2e Slave terminated */ -#define TSI148_LCSR_VEAT_BERR (1<<19) /* Bus Error */ -#define TSI148_LCSR_VEAT_LWORD (1<<18) /* LWORD_ signal state */ -#define TSI148_LCSR_VEAT_WRITE (1<<17) /* WRITE_ signal state */ -#define TSI148_LCSR_VEAT_IACK (1<<16) /* IACK_ signal state */ -#define TSI148_LCSR_VEAT_DS1 (1<<15) /* DS1_ signal state */ -#define TSI148_LCSR_VEAT_DS0 (1<<14) /* DS0_ signal state */ -#define TSI148_LCSR_VEAT_AM_M (0x3F<<8) /* Address Mode Mask */ -#define TSI148_LCSR_VEAT_XAM_M (0xFF<<0) /* Master AMode Mask */ - - -/* - * VMEbus PCI Error Diagnostics PCI/X Attributes Register CRG + $280 - */ -#define TSI148_LCSR_EDPAT_EDPCL (1<<29) - -/* - * Inbound Translation Starting Address Lower - */ -#define TSI148_LCSR_ITSAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITSAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITSAL16_M (0x0000FFF<<4) /* Mask */ - -/* - * Inbound Translation Ending Address Lower - */ -#define TSI148_LCSR_ITEAL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITEAL24_M (0x00FFF<<12) /* Mask */ -#define TSI148_LCSR_ITEAL16_M (0x0000FFF<<4) /* Mask */ - -/* - * Inbound Translation Offset Lower - */ -#define TSI148_LCSR_ITOFFL6432_M (0xFFFF<<16) /* Mask */ -#define TSI148_LCSR_ITOFFL24_M (0xFFFFF<<12) /* Mask */ -#define TSI148_LCSR_ITOFFL16_M (0xFFFFFFF<<4) /* Mask */ - -/* - * Inbound Translation Attribute - */ -#define TSI148_LCSR_ITAT_EN (1<<31) /* Window Enable */ -#define TSI148_LCSR_ITAT_TH (1<<18) /* Prefetch Threshold */ - -#define TSI148_LCSR_ITAT_VFS_M (3<<16) /* Virtual FIFO Size Mask */ -#define TSI148_LCSR_ITAT_VFS_64 (0<<16) /* 64 bytes Virtual FIFO Size */ -#define TSI148_LCSR_ITAT_VFS_128 (1<<16) /* 128 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_256 (2<<16) /* 256 bytes Virtual FIFO Sz */ -#define TSI148_LCSR_ITAT_VFS_512 (3<<16) /* 512 bytes Virtual FIFO Sz */ - -#define TSI148_LCSR_ITAT_2eSSTM_M (7<<12) /* 2eSST Xfer Rate Mask */ -#define TSI148_LCSR_ITAT_2eSSTM_160 (0<<12) /* 160MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_ITAT_2eSSTM_267 (1<<12) /* 267MB/s 2eSST Xfer Rate */ -#define TSI148_LCSR_ITAT_2eSSTM_320 (2<<12) /* 320MB/s 2eSST Xfer Rate */ - -#define TSI148_LCSR_ITAT_2eSSTB (1<<11) /* 2eSST Bcast Xfer Protocol */ -#define TSI148_LCSR_ITAT_2eSST (1<<10) /* 2eSST Xfer Protocol */ -#define TSI148_LCSR_ITAT_2eVME (1<<9) /* 2eVME Xfer Protocol */ -#define TSI148_LCSR_ITAT_MBLT (1<<8) /* MBLT Xfer Protocol */ -#define TSI148_LCSR_ITAT_BLT (1<<7) /* BLT Xfer Protocol */ - -#define TSI148_LCSR_ITAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_ITAT_AS_A16 (0<<4) /* A16 Address Space */ -#define TSI148_LCSR_ITAT_AS_A24 (1<<4) /* A24 Address Space */ -#define TSI148_LCSR_ITAT_AS_A32 (2<<4) /* A32 Address Space */ -#define TSI148_LCSR_ITAT_AS_A64 (4<<4) /* A64 Address Space */ - -#define TSI148_LCSR_ITAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_ITAT_NPRIV (1<<2) /* Non-Priv (User) Access */ -#define TSI148_LCSR_ITAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_ITAT_DATA (1<<0) /* Data Access */ - -/* - * GCSR Base Address Lower Address CRG +$404 - */ -#define TSI148_LCSR_GBAL_M (0x7FFFFFF<<5) /* Mask */ - -/* - * GCSR Attribute Register CRG + $408 - */ -#define TSI148_LCSR_GCSRAT_EN (1<<7) /* Enable access to GCSR */ - -#define TSI148_LCSR_GCSRAT_AS_M (7<<4) /* Address Space Mask */ -#define TSI148_LCSR_GCSRAT_AS_A16 (0<<4) /* Address Space 16 */ -#define TSI148_LCSR_GCSRAT_AS_A24 (1<<4) /* Address Space 24 */ -#define TSI148_LCSR_GCSRAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_GCSRAT_AS_A64 (4<<4) /* Address Space 64 */ - -#define TSI148_LCSR_GCSRAT_SUPR (1<<3) /* Sup set -GCSR decoder */ -#define TSI148_LCSR_GCSRAT_NPRIV (1<<2) /* Non-Privliged set - CGSR */ -#define TSI148_LCSR_GCSRAT_PGM (1<<1) /* Program set - GCSR decoder */ -#define TSI148_LCSR_GCSRAT_DATA (1<<0) /* DATA set GCSR decoder */ - -/* - * CRG Base Address Lower Address CRG + $410 - */ -#define TSI148_LCSR_CBAL_M (0xFFFFF<<12) - -/* - * CRG Attribute Register CRG + $414 - */ -#define TSI148_LCSR_CRGAT_EN (1<<7) /* Enable PRG Access */ - -#define TSI148_LCSR_CRGAT_AS_M (7<<4) /* Address Space */ -#define TSI148_LCSR_CRGAT_AS_A16 (0<<4) /* Address Space 16 */ -#define TSI148_LCSR_CRGAT_AS_A24 (1<<4) /* Address Space 24 */ -#define TSI148_LCSR_CRGAT_AS_A32 (2<<4) /* Address Space 32 */ -#define TSI148_LCSR_CRGAT_AS_A64 (4<<4) /* Address Space 64 */ - -#define TSI148_LCSR_CRGAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_CRGAT_NPRIV (1<<2) /* Non-Privliged(User) Access */ -#define TSI148_LCSR_CRGAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_CRGAT_DATA (1<<0) /* Data Access */ - -/* - * CR/CSR Offset Lower Register CRG + $41C - */ -#define TSI148_LCSR_CROL_M (0x1FFF<<19) /* Mask */ - -/* - * CR/CSR Attribute register CRG + $420 - */ -#define TSI148_LCSR_CRAT_EN (1<<7) /* Enable access to CR/CSR */ - -/* - * Location Monitor base address lower register CRG + $428 - */ -#define TSI148_LCSR_LMBAL_M (0x7FFFFFF<<5) /* Mask */ - -/* - * Location Monitor Attribute Register CRG + $42C - */ -#define TSI148_LCSR_LMAT_EN (1<<7) /* Enable Location Monitor */ - -#define TSI148_LCSR_LMAT_AS_M (7<<4) /* Address Space MASK */ -#define TSI148_LCSR_LMAT_AS_A16 (0<<4) /* A16 */ -#define TSI148_LCSR_LMAT_AS_A24 (1<<4) /* A24 */ -#define TSI148_LCSR_LMAT_AS_A32 (2<<4) /* A32 */ -#define TSI148_LCSR_LMAT_AS_A64 (4<<4) /* A64 */ - -#define TSI148_LCSR_LMAT_SUPR (1<<3) /* Supervisor Access */ -#define TSI148_LCSR_LMAT_NPRIV (1<<2) /* Non-Priv (User) Access */ -#define TSI148_LCSR_LMAT_PGM (1<<1) /* Program Access */ -#define TSI148_LCSR_LMAT_DATA (1<<0) /* Data Access */ - -/* - * Broadcast Pulse Generator Timer Register CRG + $438 - */ -#define TSI148_LCSR_BPGTR_BPGT_M (0xFFFF<<0) /* Mask */ - -/* - * Broadcast Programmable Clock Timer Register CRG + $43C - */ -#define TSI148_LCSR_BPCTR_BPCT_M (0xFFFFFF<<0) /* Mask */ - -/* - * VMEbus Interrupt Control Register CRG + $43C - */ -#define TSI148_LCSR_VICR_CNTS_M (3<<22) /* Cntr Source MASK */ -#define TSI148_LCSR_VICR_CNTS_DIS (1<<22) /* Cntr Disable */ -#define TSI148_LCSR_VICR_CNTS_IRQ1 (2<<22) /* IRQ1 to Cntr */ -#define TSI148_LCSR_VICR_CNTS_IRQ2 (3<<22) /* IRQ2 to Cntr */ - -#define TSI148_LCSR_VICR_EDGIS_M (3<<20) /* Edge interrupt MASK */ -#define TSI148_LCSR_VICR_EDGIS_DIS (1<<20) /* Edge interrupt Disable */ -#define TSI148_LCSR_VICR_EDGIS_IRQ1 (2<<20) /* IRQ1 to Edge */ -#define TSI148_LCSR_VICR_EDGIS_IRQ2 (3<<20) /* IRQ2 to Edge */ - -#define TSI148_LCSR_VICR_IRQIF_M (3<<18) /* IRQ1* Function MASK */ -#define TSI148_LCSR_VICR_IRQIF_NORM (1<<18) /* Normal */ -#define TSI148_LCSR_VICR_IRQIF_PULSE (2<<18) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQIF_PROG (3<<18) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQIF_1U (4<<18) /* 1us Clock */ - -#define TSI148_LCSR_VICR_IRQ2F_M (3<<16) /* IRQ2* Function MASK */ -#define TSI148_LCSR_VICR_IRQ2F_NORM (1<<16) /* Normal */ -#define TSI148_LCSR_VICR_IRQ2F_PULSE (2<<16) /* Pulse Generator */ -#define TSI148_LCSR_VICR_IRQ2F_PROG (3<<16) /* Programmable Clock */ -#define TSI148_LCSR_VICR_IRQ2F_1U (4<<16) /* 1us Clock */ - -#define TSI148_LCSR_VICR_BIP (1<<15) /* Broadcast Interrupt Pulse */ - -#define TSI148_LCSR_VICR_IRQC (1<<12) /* VMEbus IRQ Clear */ -#define TSI148_LCSR_VICR_IRQS (1<<11) /* VMEbus IRQ Status */ - -#define TSI148_LCSR_VICR_IRQL_M (7<<8) /* VMEbus SW IRQ Level Mask */ -#define TSI148_LCSR_VICR_IRQL_1 (1<<8) /* VMEbus SW IRQ Level 1 */ -#define TSI148_LCSR_VICR_IRQL_2 (2<<8) /* VMEbus SW IRQ Level 2 */ -#define TSI148_LCSR_VICR_IRQL_3 (3<<8) /* VMEbus SW IRQ Level 3 */ -#define TSI148_LCSR_VICR_IRQL_4 (4<<8) /* VMEbus SW IRQ Level 4 */ -#define TSI148_LCSR_VICR_IRQL_5 (5<<8) /* VMEbus SW IRQ Level 5 */ -#define TSI148_LCSR_VICR_IRQL_6 (6<<8) /* VMEbus SW IRQ Level 6 */ -#define TSI148_LCSR_VICR_IRQL_7 (7<<8) /* VMEbus SW IRQ Level 7 */ - -static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1, - TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3, - TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5, - TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 }; - -#define TSI148_LCSR_VICR_STID_M (0xFF<<0) /* Status/ID Mask */ - -/* - * Interrupt Enable Register CRG + $440 - */ -#define TSI148_LCSR_INTEN_DMA1EN (1<<25) /* DMAC 1 */ -#define TSI148_LCSR_INTEN_DMA0EN (1<<24) /* DMAC 0 */ -#define TSI148_LCSR_INTEN_LM3EN (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTEN_LM2EN (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTEN_LM1EN (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTEN_LM0EN (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTEN_MB3EN (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTEN_MB2EN (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTEN_MB1EN (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTEN_MB0EN (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTEN_PERREN (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTEN_VERREN (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTEN_VIEEN (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTEN_IACKEN (1<<10) /* IACK */ -#define TSI148_LCSR_INTEN_SYSFLEN (1<<9) /* System Fail */ -#define TSI148_LCSR_INTEN_ACFLEN (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTEN_IRQ7EN (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTEN_IRQ6EN (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTEN_IRQ5EN (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTEN_IRQ4EN (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTEN_IRQ3EN (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTEN_IRQ2EN (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTEN_IRQ1EN (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTEN_LMEN[4] = { TSI148_LCSR_INTEN_LM0EN, - TSI148_LCSR_INTEN_LM1EN, - TSI148_LCSR_INTEN_LM2EN, - TSI148_LCSR_INTEN_LM3EN }; - -static const int TSI148_LCSR_INTEN_IRQEN[7] = { TSI148_LCSR_INTEN_IRQ1EN, - TSI148_LCSR_INTEN_IRQ2EN, - TSI148_LCSR_INTEN_IRQ3EN, - TSI148_LCSR_INTEN_IRQ4EN, - TSI148_LCSR_INTEN_IRQ5EN, - TSI148_LCSR_INTEN_IRQ6EN, - TSI148_LCSR_INTEN_IRQ7EN }; - -/* - * Interrupt Enable Out Register CRG + $444 - */ -#define TSI148_LCSR_INTEO_DMA1EO (1<<25) /* DMAC 1 */ -#define TSI148_LCSR_INTEO_DMA0EO (1<<24) /* DMAC 0 */ -#define TSI148_LCSR_INTEO_LM3EO (1<<23) /* Loc Monitor 3 */ -#define TSI148_LCSR_INTEO_LM2EO (1<<22) /* Loc Monitor 2 */ -#define TSI148_LCSR_INTEO_LM1EO (1<<21) /* Loc Monitor 1 */ -#define TSI148_LCSR_INTEO_LM0EO (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTEO_MB3EO (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTEO_MB2EO (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTEO_MB1EO (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTEO_MB0EO (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTEO_PERREO (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTEO_VERREO (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTEO_VIEEO (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTEO_IACKEO (1<<10) /* IACK */ -#define TSI148_LCSR_INTEO_SYSFLEO (1<<9) /* System Fail */ -#define TSI148_LCSR_INTEO_ACFLEO (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTEO_IRQ7EO (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTEO_IRQ6EO (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTEO_IRQ5EO (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTEO_IRQ4EO (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTEO_IRQ3EO (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTEO_IRQ2EO (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTEO_IRQ1EO (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTEO_LMEO[4] = { TSI148_LCSR_INTEO_LM0EO, - TSI148_LCSR_INTEO_LM1EO, - TSI148_LCSR_INTEO_LM2EO, - TSI148_LCSR_INTEO_LM3EO }; - -static const int TSI148_LCSR_INTEO_IRQEO[7] = { TSI148_LCSR_INTEO_IRQ1EO, - TSI148_LCSR_INTEO_IRQ2EO, - TSI148_LCSR_INTEO_IRQ3EO, - TSI148_LCSR_INTEO_IRQ4EO, - TSI148_LCSR_INTEO_IRQ5EO, - TSI148_LCSR_INTEO_IRQ6EO, - TSI148_LCSR_INTEO_IRQ7EO }; - -/* - * Interrupt Status Register CRG + $448 - */ -#define TSI148_LCSR_INTS_DMA1S (1<<25) /* DMA 1 */ -#define TSI148_LCSR_INTS_DMA0S (1<<24) /* DMA 0 */ -#define TSI148_LCSR_INTS_LM3S (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTS_LM2S (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTS_LM1S (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTS_LM0S (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTS_MB3S (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTS_MB2S (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTS_MB1S (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTS_MB0S (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTS_PERRS (1<<13) /* PCI/X Error */ -#define TSI148_LCSR_INTS_VERRS (1<<12) /* VMEbus Error */ -#define TSI148_LCSR_INTS_VIES (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTS_IACKS (1<<10) /* IACK */ -#define TSI148_LCSR_INTS_SYSFLS (1<<9) /* System Fail */ -#define TSI148_LCSR_INTS_ACFLS (1<<8) /* AC Fail */ -#define TSI148_LCSR_INTS_IRQ7S (1<<7) /* IRQ7 */ -#define TSI148_LCSR_INTS_IRQ6S (1<<6) /* IRQ6 */ -#define TSI148_LCSR_INTS_IRQ5S (1<<5) /* IRQ5 */ -#define TSI148_LCSR_INTS_IRQ4S (1<<4) /* IRQ4 */ -#define TSI148_LCSR_INTS_IRQ3S (1<<3) /* IRQ3 */ -#define TSI148_LCSR_INTS_IRQ2S (1<<2) /* IRQ2 */ -#define TSI148_LCSR_INTS_IRQ1S (1<<1) /* IRQ1 */ - -static const int TSI148_LCSR_INTS_LMS[4] = { TSI148_LCSR_INTS_LM0S, - TSI148_LCSR_INTS_LM1S, - TSI148_LCSR_INTS_LM2S, - TSI148_LCSR_INTS_LM3S }; - -static const int TSI148_LCSR_INTS_MBS[4] = { TSI148_LCSR_INTS_MB0S, - TSI148_LCSR_INTS_MB1S, - TSI148_LCSR_INTS_MB2S, - TSI148_LCSR_INTS_MB3S }; - -/* - * Interrupt Clear Register CRG + $44C - */ -#define TSI148_LCSR_INTC_DMA1C (1<<25) /* DMA 1 */ -#define TSI148_LCSR_INTC_DMA0C (1<<24) /* DMA 0 */ -#define TSI148_LCSR_INTC_LM3C (1<<23) /* Location Monitor 3 */ -#define TSI148_LCSR_INTC_LM2C (1<<22) /* Location Monitor 2 */ -#define TSI148_LCSR_INTC_LM1C (1<<21) /* Location Monitor 1 */ -#define TSI148_LCSR_INTC_LM0C (1<<20) /* Location Monitor 0 */ -#define TSI148_LCSR_INTC_MB3C (1<<19) /* Mail Box 3 */ -#define TSI148_LCSR_INTC_MB2C (1<<18) /* Mail Box 2 */ -#define TSI148_LCSR_INTC_MB1C (1<<17) /* Mail Box 1 */ -#define TSI148_LCSR_INTC_MB0C (1<<16) /* Mail Box 0 */ -#define TSI148_LCSR_INTC_PERRC (1<<13) /* VMEbus Error */ -#define TSI148_LCSR_INTC_VERRC (1<<12) /* VMEbus Access Time-out */ -#define TSI148_LCSR_INTC_VIEC (1<<11) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTC_IACKC (1<<10) /* IACK */ -#define TSI148_LCSR_INTC_SYSFLC (1<<9) /* System Fail */ -#define TSI148_LCSR_INTC_ACFLC (1<<8) /* AC Fail */ - -static const int TSI148_LCSR_INTC_LMC[4] = { TSI148_LCSR_INTC_LM0C, - TSI148_LCSR_INTC_LM1C, - TSI148_LCSR_INTC_LM2C, - TSI148_LCSR_INTC_LM3C }; - -static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C, - TSI148_LCSR_INTC_MB1C, - TSI148_LCSR_INTC_MB2C, - TSI148_LCSR_INTC_MB3C }; - -/* - * Interrupt Map Register 1 CRG + $458 - */ -#define TSI148_LCSR_INTM1_DMA1M_M (3<<18) /* DMA 1 */ -#define TSI148_LCSR_INTM1_DMA0M_M (3<<16) /* DMA 0 */ -#define TSI148_LCSR_INTM1_LM3M_M (3<<14) /* Location Monitor 3 */ -#define TSI148_LCSR_INTM1_LM2M_M (3<<12) /* Location Monitor 2 */ -#define TSI148_LCSR_INTM1_LM1M_M (3<<10) /* Location Monitor 1 */ -#define TSI148_LCSR_INTM1_LM0M_M (3<<8) /* Location Monitor 0 */ -#define TSI148_LCSR_INTM1_MB3M_M (3<<6) /* Mail Box 3 */ -#define TSI148_LCSR_INTM1_MB2M_M (3<<4) /* Mail Box 2 */ -#define TSI148_LCSR_INTM1_MB1M_M (3<<2) /* Mail Box 1 */ -#define TSI148_LCSR_INTM1_MB0M_M (3<<0) /* Mail Box 0 */ - -/* - * Interrupt Map Register 2 CRG + $45C - */ -#define TSI148_LCSR_INTM2_PERRM_M (3<<26) /* PCI Bus Error */ -#define TSI148_LCSR_INTM2_VERRM_M (3<<24) /* VMEbus Error */ -#define TSI148_LCSR_INTM2_VIEM_M (3<<22) /* VMEbus IRQ Edge */ -#define TSI148_LCSR_INTM2_IACKM_M (3<<20) /* IACK */ -#define TSI148_LCSR_INTM2_SYSFLM_M (3<<18) /* System Fail */ -#define TSI148_LCSR_INTM2_ACFLM_M (3<<16) /* AC Fail */ -#define TSI148_LCSR_INTM2_IRQ7M_M (3<<14) /* IRQ7 */ -#define TSI148_LCSR_INTM2_IRQ6M_M (3<<12) /* IRQ6 */ -#define TSI148_LCSR_INTM2_IRQ5M_M (3<<10) /* IRQ5 */ -#define TSI148_LCSR_INTM2_IRQ4M_M (3<<8) /* IRQ4 */ -#define TSI148_LCSR_INTM2_IRQ3M_M (3<<6) /* IRQ3 */ -#define TSI148_LCSR_INTM2_IRQ2M_M (3<<4) /* IRQ2 */ -#define TSI148_LCSR_INTM2_IRQ1M_M (3<<2) /* IRQ1 */ - -/* - * DMA Control (0-1) Registers CRG + $500 - */ -#define TSI148_LCSR_DCTL_ABT (1<<27) /* Abort */ -#define TSI148_LCSR_DCTL_PAU (1<<26) /* Pause */ -#define TSI148_LCSR_DCTL_DGO (1<<25) /* DMA Go */ - -#define TSI148_LCSR_DCTL_MOD (1<<23) /* Mode */ - -#define TSI148_LCSR_DCTL_VBKS_M (7<<12) /* VMEbus block Size MASK */ -#define TSI148_LCSR_DCTL_VBKS_32 (0<<12) /* VMEbus block Size 32 */ -#define TSI148_LCSR_DCTL_VBKS_64 (1<<12) /* VMEbus block Size 64 */ -#define TSI148_LCSR_DCTL_VBKS_128 (2<<12) /* VMEbus block Size 128 */ -#define TSI148_LCSR_DCTL_VBKS_256 (3<<12) /* VMEbus block Size 256 */ -#define TSI148_LCSR_DCTL_VBKS_512 (4<<12) /* VMEbus block Size 512 */ -#define TSI148_LCSR_DCTL_VBKS_1024 (5<<12) /* VMEbus block Size 1024 */ -#define TSI148_LCSR_DCTL_VBKS_2048 (6<<12) /* VMEbus block Size 2048 */ -#define TSI148_LCSR_DCTL_VBKS_4096 (7<<12) /* VMEbus block Size 4096 */ - -#define TSI148_LCSR_DCTL_VBOT_M (7<<8) /* VMEbus back-off MASK */ -#define TSI148_LCSR_DCTL_VBOT_0 (0<<8) /* VMEbus back-off 0us */ -#define TSI148_LCSR_DCTL_VBOT_1 (1<<8) /* VMEbus back-off 1us */ -#define TSI148_LCSR_DCTL_VBOT_2 (2<<8) /* VMEbus back-off 2us */ -#define TSI148_LCSR_DCTL_VBOT_4 (3<<8) /* VMEbus back-off 4us */ -#define TSI148_LCSR_DCTL_VBOT_8 (4<<8) /* VMEbus back-off 8us */ -#define TSI148_LCSR_DCTL_VBOT_16 (5<<8) /* VMEbus back-off 16us */ -#define TSI148_LCSR_DCTL_VBOT_32 (6<<8) /* VMEbus back-off 32us */ -#define TSI148_LCSR_DCTL_VBOT_64 (7<<8) /* VMEbus back-off 64us */ - -#define TSI148_LCSR_DCTL_PBKS_M (7<<4) /* PCI block size MASK */ -#define TSI148_LCSR_DCTL_PBKS_32 (0<<4) /* PCI block size 32 bytes */ -#define TSI148_LCSR_DCTL_PBKS_64 (1<<4) /* PCI block size 64 bytes */ -#define TSI148_LCSR_DCTL_PBKS_128 (2<<4) /* PCI block size 128 bytes */ -#define TSI148_LCSR_DCTL_PBKS_256 (3<<4) /* PCI block size 256 bytes */ -#define TSI148_LCSR_DCTL_PBKS_512 (4<<4) /* PCI block size 512 bytes */ -#define TSI148_LCSR_DCTL_PBKS_1024 (5<<4) /* PCI block size 1024 bytes */ -#define TSI148_LCSR_DCTL_PBKS_2048 (6<<4) /* PCI block size 2048 bytes */ -#define TSI148_LCSR_DCTL_PBKS_4096 (7<<4) /* PCI block size 4096 bytes */ - -#define TSI148_LCSR_DCTL_PBOT_M (7<<0) /* PCI back off MASK */ -#define TSI148_LCSR_DCTL_PBOT_0 (0<<0) /* PCI back off 0us */ -#define TSI148_LCSR_DCTL_PBOT_1 (1<<0) /* PCI back off 1us */ -#define TSI148_LCSR_DCTL_PBOT_2 (2<<0) /* PCI back off 2us */ -#define TSI148_LCSR_DCTL_PBOT_4 (3<<0) /* PCI back off 3us */ -#define TSI148_LCSR_DCTL_PBOT_8 (4<<0) /* PCI back off 4us */ -#define TSI148_LCSR_DCTL_PBOT_16 (5<<0) /* PCI back off 8us */ -#define TSI148_LCSR_DCTL_PBOT_32 (6<<0) /* PCI back off 16us */ -#define TSI148_LCSR_DCTL_PBOT_64 (7<<0) /* PCI back off 32us */ - -/* - * DMA Status Registers (0-1) CRG + $504 - */ -#define TSI148_LCSR_DSTA_SMA (1<<31) /* PCI Signalled Master Abt */ -#define TSI148_LCSR_DSTA_RTA (1<<30) /* PCI Received Target Abt */ -#define TSI148_LCSR_DSTA_MRC (1<<29) /* PCI Max Retry Count */ -#define TSI148_LCSR_DSTA_VBE (1<<28) /* VMEbus error */ -#define TSI148_LCSR_DSTA_ABT (1<<27) /* Abort */ -#define TSI148_LCSR_DSTA_PAU (1<<26) /* Pause */ -#define TSI148_LCSR_DSTA_DON (1<<25) /* Done */ -#define TSI148_LCSR_DSTA_BSY (1<<24) /* Busy */ - -/* - * DMA Current Link Address Lower (0-1) - */ -#define TSI148_LCSR_DCLAL_M (0x3FFFFFF<<6) /* Mask */ - -/* - * DMA Source Attribute (0-1) Reg - */ -#define TSI148_LCSR_DSAT_TYP_M (3<<28) /* Source Bus Type */ -#define TSI148_LCSR_DSAT_TYP_PCI (0<<28) /* PCI Bus */ -#define TSI148_LCSR_DSAT_TYP_VME (1<<28) /* VMEbus */ -#define TSI148_LCSR_DSAT_TYP_PAT (2<<28) /* Data Pattern */ - -#define TSI148_LCSR_DSAT_PSZ (1<<25) /* Pattern Size */ -#define TSI148_LCSR_DSAT_NIN (1<<24) /* No Increment */ - -#define TSI148_LCSR_DSAT_2eSSTM_M (3<<11) /* 2eSST Trans Rate Mask */ -#define TSI148_LCSR_DSAT_2eSSTM_160 (0<<11) /* 160 MB/s */ -#define TSI148_LCSR_DSAT_2eSSTM_267 (1<<11) /* 267 MB/s */ -#define TSI148_LCSR_DSAT_2eSSTM_320 (2<<11) /* 320 MB/s */ - -#define TSI148_LCSR_DSAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DSAT_TM_SCT (0<<8) /* SCT */ -#define TSI148_LCSR_DSAT_TM_BLT (1<<8) /* BLT */ -#define TSI148_LCSR_DSAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DSAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DSAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DSAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ - -#define TSI148_LCSR_DSAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DSAT_DBW_16 (0<<6) /* 16 Bits */ -#define TSI148_LCSR_DSAT_DBW_32 (1<<6) /* 32 Bits */ - -#define TSI148_LCSR_DSAT_SUP (1<<5) /* Supervisory Mode */ -#define TSI148_LCSR_DSAT_PGM (1<<4) /* Program Mode */ - -#define TSI148_LCSR_DSAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DSAT_AMODE_A16 (0<<0) /* A16 */ -#define TSI148_LCSR_DSAT_AMODE_A24 (1<<0) /* A24 */ -#define TSI148_LCSR_DSAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DSAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DSAT_AMODE_CRCSR (5<<0) /* CR/CSR */ -#define TSI148_LCSR_DSAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DSAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DSAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DSAT_AMODE_USER4 (0xb<<0) /* User4 */ - -/* - * DMA Destination Attribute Registers (0-1) - */ -#define TSI148_LCSR_DDAT_TYP_PCI (0<<28) /* Destination PCI Bus */ -#define TSI148_LCSR_DDAT_TYP_VME (1<<28) /* Destination VMEbus */ - -#define TSI148_LCSR_DDAT_2eSSTM_M (3<<11) /* 2eSST Transfer Rate Mask */ -#define TSI148_LCSR_DDAT_2eSSTM_160 (0<<11) /* 160 MB/s */ -#define TSI148_LCSR_DDAT_2eSSTM_267 (1<<11) /* 267 MB/s */ -#define TSI148_LCSR_DDAT_2eSSTM_320 (2<<11) /* 320 MB/s */ - -#define TSI148_LCSR_DDAT_TM_M (7<<8) /* Bus Transfer Protocol Mask */ -#define TSI148_LCSR_DDAT_TM_SCT (0<<8) /* SCT */ -#define TSI148_LCSR_DDAT_TM_BLT (1<<8) /* BLT */ -#define TSI148_LCSR_DDAT_TM_MBLT (2<<8) /* MBLT */ -#define TSI148_LCSR_DDAT_TM_2eVME (3<<8) /* 2eVME */ -#define TSI148_LCSR_DDAT_TM_2eSST (4<<8) /* 2eSST */ -#define TSI148_LCSR_DDAT_TM_2eSSTB (5<<8) /* 2eSST Broadcast */ - -#define TSI148_LCSR_DDAT_DBW_M (3<<6) /* Max Data Width MASK */ -#define TSI148_LCSR_DDAT_DBW_16 (0<<6) /* 16 Bits */ -#define TSI148_LCSR_DDAT_DBW_32 (1<<6) /* 32 Bits */ - -#define TSI148_LCSR_DDAT_SUP (1<<5) /* Supervisory/User Access */ -#define TSI148_LCSR_DDAT_PGM (1<<4) /* Program/Data Access */ - -#define TSI148_LCSR_DDAT_AMODE_M (0xf<<0) /* Address Space Mask */ -#define TSI148_LCSR_DDAT_AMODE_A16 (0<<0) /* A16 */ -#define TSI148_LCSR_DDAT_AMODE_A24 (1<<0) /* A24 */ -#define TSI148_LCSR_DDAT_AMODE_A32 (2<<0) /* A32 */ -#define TSI148_LCSR_DDAT_AMODE_A64 (4<<0) /* A64 */ -#define TSI148_LCSR_DDAT_AMODE_CRCSR (5<<0) /* CRC/SR */ -#define TSI148_LCSR_DDAT_AMODE_USER1 (8<<0) /* User1 */ -#define TSI148_LCSR_DDAT_AMODE_USER2 (9<<0) /* User2 */ -#define TSI148_LCSR_DDAT_AMODE_USER3 (0xa<<0) /* User3 */ -#define TSI148_LCSR_DDAT_AMODE_USER4 (0xb<<0) /* User4 */ - -/* - * DMA Next Link Address Lower - */ -#define TSI148_LCSR_DNLAL_DNLAL_M (0x3FFFFFF<<6) /* Address Mask */ -#define TSI148_LCSR_DNLAL_LLA (1<<0) /* Last Link Address Indicator */ - -/* - * DMA 2eSST Broadcast Select - */ -#define TSI148_LCSR_DBS_M (0x1FFFFF<<0) /* Mask */ - -/* - * GCSR Register Group - */ - -/* - * GCSR Control and Status Register CRG + $604 - */ -#define TSI148_GCSR_GCTRL_LRST (1<<15) /* Local Reset */ -#define TSI148_GCSR_GCTRL_SFAILEN (1<<14) /* System Fail enable */ -#define TSI148_GCSR_GCTRL_BDFAILS (1<<13) /* Board Fail Status */ -#define TSI148_GCSR_GCTRL_SCON (1<<12) /* System Copntroller */ -#define TSI148_GCSR_GCTRL_MEN (1<<11) /* Module Enable (READY) */ - -#define TSI148_GCSR_GCTRL_LMI3S (1<<7) /* Loc Monitor 3 Int Status */ -#define TSI148_GCSR_GCTRL_LMI2S (1<<6) /* Loc Monitor 2 Int Status */ -#define TSI148_GCSR_GCTRL_LMI1S (1<<5) /* Loc Monitor 1 Int Status */ -#define TSI148_GCSR_GCTRL_LMI0S (1<<4) /* Loc Monitor 0 Int Status */ -#define TSI148_GCSR_GCTRL_MBI3S (1<<3) /* Mail box 3 Int Status */ -#define TSI148_GCSR_GCTRL_MBI2S (1<<2) /* Mail box 2 Int Status */ -#define TSI148_GCSR_GCTRL_MBI1S (1<<1) /* Mail box 1 Int Status */ -#define TSI148_GCSR_GCTRL_MBI0S (1<<0) /* Mail box 0 Int Status */ - -#define TSI148_GCSR_GAP (1<<5) /* Geographic Addr Parity */ -#define TSI148_GCSR_GA_M (0x1F<<0) /* Geographic Address Mask */ - -/* - * CR/CSR Register Group - */ - -/* - * CR/CSR Bit Clear Register CRG + $FF4 - */ -#define TSI148_CRCSR_CSRBCR_LRSTC (1<<7) /* Local Reset Clear */ -#define TSI148_CRCSR_CSRBCR_SFAILC (1<<6) /* System Fail Enable Clear */ -#define TSI148_CRCSR_CSRBCR_BDFAILS (1<<5) /* Board Fail Status */ -#define TSI148_CRCSR_CSRBCR_MENC (1<<4) /* Module Enable Clear */ -#define TSI148_CRCSR_CSRBCR_BERRSC (1<<3) /* Bus Error Status Clear */ - -/* - * CR/CSR Bit Set Register CRG+$FF8 - */ -#define TSI148_CRCSR_CSRBSR_LISTS (1<<7) /* Local Reset Clear */ -#define TSI148_CRCSR_CSRBSR_SFAILS (1<<6) /* System Fail Enable Clear */ -#define TSI148_CRCSR_CSRBSR_BDFAILS (1<<5) /* Board Fail Status */ -#define TSI148_CRCSR_CSRBSR_MENS (1<<4) /* Module Enable Clear */ -#define TSI148_CRCSR_CSRBSR_BERRS (1<<3) /* Bus Error Status Clear */ - -/* - * CR/CSR Base Address Register CRG + FFC - */ -#define TSI148_CRCSR_CBAR_M (0x1F<<3) /* Mask */ - -#endif /* TSI148_H */ diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig index 55ec30c..d0cab17 100644 --- a/drivers/staging/vme/devices/Kconfig +++ b/drivers/staging/vme/devices/Kconfig @@ -2,6 +2,7 @@ comment "VME Device Drivers" config VME_USER tristate "VME user space access driver" + depends on STAGING help If you say Y here you want to be able to access a limited number of VME windows in a manner at least semi-compatible with the interface @@ -9,7 +10,7 @@ config VME_USER config VME_PIO2 tristate "GE PIO2 VME" - depends on GPIOLIB + depends on STAGING && GPIOLIB help Say Y here to include support for the GE PIO2. The PIO2 is a 6U VME slave card, implementing 32 solid-state relay switched IO lines, in diff --git a/drivers/staging/vme/devices/vme_pio2_cntr.c b/drivers/staging/vme/devices/vme_pio2_cntr.c index 08e0d59..6335471 100644 --- a/drivers/staging/vme/devices/vme_pio2_cntr.c +++ b/drivers/staging/vme/devices/vme_pio2_cntr.c @@ -17,8 +17,8 @@ #include <linux/device.h> #include <linux/types.h> #include <linux/gpio.h> +#include <linux/vme.h> -#include "../vme.h" #include "vme_pio2.h" static int pio2_cntr_irq_set(struct pio2_card *card, int id) diff --git a/drivers/staging/vme/devices/vme_pio2_core.c b/drivers/staging/vme/devices/vme_pio2_core.c index 573c800..4bf8e05 100644 --- a/drivers/staging/vme/devices/vme_pio2_core.c +++ b/drivers/staging/vme/devices/vme_pio2_core.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include <linux/version.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> @@ -20,8 +19,8 @@ #include <linux/ctype.h> #include <linux/gpio.h> #include <linux/slab.h> +#include <linux/vme.h> -#include "../vme.h" #include "vme_pio2.h" diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c index 8584849..ad76a47 100644 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ b/drivers/staging/vme/devices/vme_pio2_gpio.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include <linux/version.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> @@ -21,8 +20,8 @@ #include <linux/ctype.h> #include <linux/gpio.h> #include <linux/slab.h> +#include <linux/vme.h> -#include "../vme.h" #include "vme_pio2.h" static const char driver_name[] = "pio2_gpio"; @@ -79,7 +78,7 @@ static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset, if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not availabe as output\n"); + dev_err(&card->vdev->dev, "Channel not available as output\n"); return; } diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 7dcd162..e24a6f9 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -27,7 +27,7 @@ #include <linux/module.h> #include <linux/pagemap.h> #include <linux/pci.h> -#include <linux/semaphore.h> +#include <linux/mutex.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/syscalls.h> @@ -36,8 +36,8 @@ #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/vme.h> -#include "../vme.h" #include "vme_user.h" static DEFINE_MUTEX(vme_user_mutex); @@ -95,7 +95,7 @@ struct image_desc { void *kern_buf; /* Buffer address in kernel space */ dma_addr_t pci_buf; /* Buffer address in PCI address space */ unsigned long long size_buf; /* Buffer size */ - struct semaphore sem; /* Semaphore for locking image */ + struct mutex mutex; /* Mutex for locking image */ struct device *device; /* Sysfs device */ struct vme_resource *resource; /* VME resource */ int users; /* Number of current users */ @@ -168,7 +168,7 @@ static int vme_user_open(struct inode *inode, struct file *file) int err; unsigned int minor = MINOR(inode->i_rdev); - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* Allow device to be opened if a resource is needed and allocated. */ if (minor < CONTROL_MINOR && image[minor].resource == NULL) { printk(KERN_ERR "No resources allocated for device\n"); @@ -179,12 +179,12 @@ static int vme_user_open(struct inode *inode, struct file *file) /* Increment user count */ image[minor].users++; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; err_res: - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return err; } @@ -193,12 +193,12 @@ static int vme_user_release(struct inode *inode, struct file *file) { unsigned int minor = MINOR(inode->i_rdev); - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* Decrement user count */ image[minor].users--; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -325,14 +325,14 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, if (minor == CONTROL_MINOR) return 0; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); /* XXX Do we *really* want this helper - we can use vme_*_get ? */ image_size = vme_get_size(image[minor].resource); /* Ensure we are starting at a valid location */ if ((*ppos < 0) || (*ppos > (image_size - 1))) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -353,8 +353,7 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, retval = -EINVAL; } - up(&image[minor].sem); - + mutex_unlock(&image[minor].mutex); if (retval > 0) *ppos += retval; @@ -372,13 +371,13 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, if (minor == CONTROL_MINOR) return 0; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); image_size = vme_get_size(image[minor].resource); /* Ensure we are starting at a valid location */ if ((*ppos < 0) || (*ppos > (image_size - 1))) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return 0; } @@ -398,8 +397,8 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, default: retval = -EINVAL; } - - up(&image[minor].sem); + + mutex_unlock(&image[minor].mutex); if (retval > 0) *ppos += retval; @@ -416,7 +415,7 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) if (minor == CONTROL_MINOR) return -EINVAL; - down(&image[minor].sem); + mutex_lock(&image[minor].mutex); image_size = vme_get_size(image[minor].resource); switch (whence) { @@ -430,19 +429,19 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) absolute = image_size + off; break; default: - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return -EINVAL; break; } if ((absolute < 0) || (absolute >= image_size)) { - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return -EINVAL; } file->f_pos = absolute; - up(&image[minor].sem); + mutex_unlock(&image[minor].mutex); return absolute; } @@ -696,7 +695,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) for (i = 0; i < VME_DEVS; i++) { image[i].kern_buf = NULL; image[i].pci_buf = 0; - sema_init(&image[i].sem, 1); + mutex_init(&image[i].mutex); image[i].device = NULL; image[i].resource = NULL; image[i].users = 0; @@ -858,8 +857,10 @@ static int __devexit vme_user_remove(struct vme_dev *dev) int i; /* Remove sysfs Entries */ - for (i = 0; i < VME_DEVS; i++) + for (i = 0; i < VME_DEVS; i++) { + mutex_destroy(&image[i].mutex); device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); + } class_destroy(vme_user_sysfs_class); for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) { diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c deleted file mode 100644 index 70722ae..0000000 --- a/drivers/staging/vme/vme.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* - * VME Bridge Framework - * - * Author: Martyn Welch <martyn.welch@ge.com> - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * Based on work by Tom Armistead and Ajit Prem - * Copyright 2004 Motorola Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/mm.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/pci.h> -#include <linux/poll.h> -#include <linux/highmem.h> -#include <linux/interrupt.h> -#include <linux/pagemap.h> -#include <linux/device.h> -#include <linux/dma-mapping.h> -#include <linux/syscalls.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> -#include <linux/slab.h> - -#include "vme.h" -#include "vme_bridge.h" - -/* Bitmask and list of registered buses both protected by common mutex */ -static unsigned int vme_bus_numbers; -static LIST_HEAD(vme_bus_list); -static DEFINE_MUTEX(vme_buses_lock); - -static void __exit vme_exit(void); -static int __init vme_init(void); - -static struct vme_dev *dev_to_vme_dev(struct device *dev) -{ - return container_of(dev, struct vme_dev, dev); -} - -/* - * Find the bridge that the resource is associated with. - */ -static struct vme_bridge *find_bridge(struct vme_resource *resource) -{ - /* Get list to search */ - switch (resource->type) { - case VME_MASTER: - return list_entry(resource->entry, struct vme_master_resource, - list)->parent; - break; - case VME_SLAVE: - return list_entry(resource->entry, struct vme_slave_resource, - list)->parent; - break; - case VME_DMA: - return list_entry(resource->entry, struct vme_dma_resource, - list)->parent; - break; - case VME_LM: - return list_entry(resource->entry, struct vme_lm_resource, - list)->parent; - break; - default: - printk(KERN_ERR "Unknown resource type\n"); - return NULL; - break; - } -} - -/* - * Allocate a contiguous block of memory for use by the driver. This is used to - * create the buffers for the slave windows. - */ -void *vme_alloc_consistent(struct vme_resource *resource, size_t size, - dma_addr_t *dma) -{ - struct vme_bridge *bridge; - - if (resource == NULL) { - printk(KERN_ERR "No resource\n"); - return NULL; - } - - bridge = find_bridge(resource); - if (bridge == NULL) { - printk(KERN_ERR "Can't find bridge\n"); - return NULL; - } - - if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for" - " bridge %s\n", bridge->name); - return NULL; - } - - if (bridge->alloc_consistent == NULL) { - printk(KERN_ERR "alloc_consistent not supported by" - " bridge %s\n", bridge->name); - return NULL; - } - - return bridge->alloc_consistent(bridge->parent, size, dma); -} -EXPORT_SYMBOL(vme_alloc_consistent); - -/* - * Free previously allocated contiguous block of memory. - */ -void vme_free_consistent(struct vme_resource *resource, size_t size, - void *vaddr, dma_addr_t dma) -{ - struct vme_bridge *bridge; - - if (resource == NULL) { - printk(KERN_ERR "No resource\n"); - return; - } - - bridge = find_bridge(resource); - if (bridge == NULL) { - printk(KERN_ERR "Can't find bridge\n"); - return; - } - - if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL for" - " bridge %s\n", bridge->name); - return; - } - - if (bridge->free_consistent == NULL) { - printk(KERN_ERR "free_consistent not supported by" - " bridge %s\n", bridge->name); - return; - } - - bridge->free_consistent(bridge->parent, size, vaddr, dma); -} -EXPORT_SYMBOL(vme_free_consistent); - -size_t vme_get_size(struct vme_resource *resource) -{ - int enabled, retval; - unsigned long long base, size; - dma_addr_t buf_base; - u32 aspace, cycle, dwidth; - - switch (resource->type) { - case VME_MASTER: - retval = vme_master_get(resource, &enabled, &base, &size, - &aspace, &cycle, &dwidth); - - return size; - break; - case VME_SLAVE: - retval = vme_slave_get(resource, &enabled, &base, &size, - &buf_base, &aspace, &cycle); - - return size; - break; - case VME_DMA: - return 0; - break; - default: - printk(KERN_ERR "Unknown resource type\n"); - return 0; - break; - } -} -EXPORT_SYMBOL(vme_get_size); - -static int vme_check_window(u32 aspace, unsigned long long vme_base, - unsigned long long size) -{ - int retval = 0; - - switch (aspace) { - case VME_A16: - if (((vme_base + size) > VME_A16_MAX) || - (vme_base > VME_A16_MAX)) - retval = -EFAULT; - break; - case VME_A24: - if (((vme_base + size) > VME_A24_MAX) || - (vme_base > VME_A24_MAX)) - retval = -EFAULT; - break; - case VME_A32: - if (((vme_base + size) > VME_A32_MAX) || - (vme_base > VME_A32_MAX)) - retval = -EFAULT; - break; - case VME_A64: - /* - * Any value held in an unsigned long long can be used as the - * base - */ - break; - case VME_CRCSR: - if (((vme_base + size) > VME_CRCSR_MAX) || - (vme_base > VME_CRCSR_MAX)) - retval = -EFAULT; - break; - case VME_USER1: - case VME_USER2: - case VME_USER3: - case VME_USER4: - /* User Defined */ - break; - default: - printk(KERN_ERR "Invalid address space\n"); - retval = -EINVAL; - break; - } - - return retval; -} - -/* - * Request a slave image with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, - u32 cycle) -{ - struct vme_bridge *bridge; - struct list_head *slave_pos = NULL; - struct vme_slave_resource *allocated_image = NULL; - struct vme_slave_resource *slave_image = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through slave resources */ - list_for_each(slave_pos, &bridge->slave_resources) { - slave_image = list_entry(slave_pos, - struct vme_slave_resource, list); - - if (slave_image == NULL) { - printk(KERN_ERR "Registered NULL Slave resource\n"); - continue; - } - - /* Find an unlocked and compatible image */ - mutex_lock(&slave_image->mtx); - if (((slave_image->address_attr & address) == address) && - ((slave_image->cycle_attr & cycle) == cycle) && - (slave_image->locked == 0)) { - - slave_image->locked = 1; - mutex_unlock(&slave_image->mtx); - allocated_image = slave_image; - break; - } - mutex_unlock(&slave_image->mtx); - } - - /* No free image */ - if (allocated_image == NULL) - goto err_image; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_WARNING "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_SLAVE; - resource->entry = &allocated_image->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&slave_image->mtx); - slave_image->locked = 0; - mutex_unlock(&slave_image->mtx); -err_image: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_slave_request); - -int vme_slave_set(struct vme_resource *resource, int enabled, - unsigned long long vme_base, unsigned long long size, - dma_addr_t buf_base, u32 aspace, u32 cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_slave_resource *image; - int retval; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_slave_resource, list); - - if (bridge->slave_set == NULL) { - printk(KERN_ERR "Function not supported\n"); - return -ENOSYS; - } - - if (!(((image->address_attr & aspace) == aspace) && - ((image->cycle_attr & cycle) == cycle))) { - printk(KERN_ERR "Invalid attributes\n"); - return -EINVAL; - } - - retval = vme_check_window(aspace, vme_base, size); - if (retval) - return retval; - - return bridge->slave_set(image, enabled, vme_base, size, buf_base, - aspace, cycle); -} -EXPORT_SYMBOL(vme_slave_set); - -int vme_slave_get(struct vme_resource *resource, int *enabled, - unsigned long long *vme_base, unsigned long long *size, - dma_addr_t *buf_base, u32 *aspace, u32 *cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_slave_resource *image; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_slave_resource, list); - - if (bridge->slave_get == NULL) { - printk(KERN_ERR "vme_slave_get not supported\n"); - return -EINVAL; - } - - return bridge->slave_get(image, enabled, vme_base, size, buf_base, - aspace, cycle); -} -EXPORT_SYMBOL(vme_slave_get); - -void vme_slave_free(struct vme_resource *resource) -{ - struct vme_slave_resource *slave_image; - - if (resource->type != VME_SLAVE) { - printk(KERN_ERR "Not a slave resource\n"); - return; - } - - slave_image = list_entry(resource->entry, struct vme_slave_resource, - list); - if (slave_image == NULL) { - printk(KERN_ERR "Can't find slave resource\n"); - return; - } - - /* Unlock image */ - mutex_lock(&slave_image->mtx); - if (slave_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); - - slave_image->locked = 0; - mutex_unlock(&slave_image->mtx); - - /* Free up resource memory */ - kfree(resource); -} -EXPORT_SYMBOL(vme_slave_free); - -/* - * Request a master image with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, - u32 cycle, u32 dwidth) -{ - struct vme_bridge *bridge; - struct list_head *master_pos = NULL; - struct vme_master_resource *allocated_image = NULL; - struct vme_master_resource *master_image = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through master resources */ - list_for_each(master_pos, &bridge->master_resources) { - master_image = list_entry(master_pos, - struct vme_master_resource, list); - - if (master_image == NULL) { - printk(KERN_WARNING "Registered NULL master resource\n"); - continue; - } - - /* Find an unlocked and compatible image */ - spin_lock(&master_image->lock); - if (((master_image->address_attr & address) == address) && - ((master_image->cycle_attr & cycle) == cycle) && - ((master_image->width_attr & dwidth) == dwidth) && - (master_image->locked == 0)) { - - master_image->locked = 1; - spin_unlock(&master_image->lock); - allocated_image = master_image; - break; - } - spin_unlock(&master_image->lock); - } - - /* Check to see if we found a resource */ - if (allocated_image == NULL) { - printk(KERN_ERR "Can't find a suitable resource\n"); - goto err_image; - } - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_ERR "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_MASTER; - resource->entry = &allocated_image->list; - - return resource; - -err_alloc: - /* Unlock image */ - spin_lock(&master_image->lock); - master_image->locked = 0; - spin_unlock(&master_image->lock); -err_image: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_master_request); - -int vme_master_set(struct vme_resource *resource, int enabled, - unsigned long long vme_base, unsigned long long size, u32 aspace, - u32 cycle, u32 dwidth) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - int retval; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - if (bridge->master_set == NULL) { - printk(KERN_WARNING "vme_master_set not supported\n"); - return -EINVAL; - } - - if (!(((image->address_attr & aspace) == aspace) && - ((image->cycle_attr & cycle) == cycle) && - ((image->width_attr & dwidth) == dwidth))) { - printk(KERN_WARNING "Invalid attributes\n"); - return -EINVAL; - } - - retval = vme_check_window(aspace, vme_base, size); - if (retval) - return retval; - - return bridge->master_set(image, enabled, vme_base, size, aspace, - cycle, dwidth); -} -EXPORT_SYMBOL(vme_master_set); - -int vme_master_get(struct vme_resource *resource, int *enabled, - unsigned long long *vme_base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *dwidth) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - if (bridge->master_get == NULL) { - printk(KERN_WARNING "vme_master_set not supported\n"); - return -EINVAL; - } - - return bridge->master_get(image, enabled, vme_base, size, aspace, - cycle, dwidth); -} -EXPORT_SYMBOL(vme_master_get); - -/* - * Read data out of VME space into a buffer. - */ -ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, - loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - size_t length; - - if (bridge->master_read == NULL) { - printk(KERN_WARNING "Reading from resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - length = vme_get_size(resource); - - if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); - return -EFAULT; - } - - if ((offset + count) > length) - count = length - offset; - - return bridge->master_read(image, buf, count, offset); - -} -EXPORT_SYMBOL(vme_master_read); - -/* - * Write data out to VME space from a buffer. - */ -ssize_t vme_master_write(struct vme_resource *resource, void *buf, - size_t count, loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - size_t length; - - if (bridge->master_write == NULL) { - printk(KERN_WARNING "Writing to resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - length = vme_get_size(resource); - - if (offset > length) { - printk(KERN_WARNING "Invalid Offset\n"); - return -EFAULT; - } - - if ((offset + count) > length) - count = length - offset; - - return bridge->master_write(image, buf, count, offset); -} -EXPORT_SYMBOL(vme_master_write); - -/* - * Perform RMW cycle to provided location. - */ -unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, - unsigned int compare, unsigned int swap, loff_t offset) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_master_resource *image; - - if (bridge->master_rmw == NULL) { - printk(KERN_WARNING "Writing to resource not supported\n"); - return -EINVAL; - } - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return -EINVAL; - } - - image = list_entry(resource->entry, struct vme_master_resource, list); - - return bridge->master_rmw(image, mask, compare, swap, offset); -} -EXPORT_SYMBOL(vme_master_rmw); - -void vme_master_free(struct vme_resource *resource) -{ - struct vme_master_resource *master_image; - - if (resource->type != VME_MASTER) { - printk(KERN_ERR "Not a master resource\n"); - return; - } - - master_image = list_entry(resource->entry, struct vme_master_resource, - list); - if (master_image == NULL) { - printk(KERN_ERR "Can't find master resource\n"); - return; - } - - /* Unlock image */ - spin_lock(&master_image->lock); - if (master_image->locked == 0) - printk(KERN_ERR "Image is already free\n"); - - master_image->locked = 0; - spin_unlock(&master_image->lock); - - /* Free up resource memory */ - kfree(resource); -} -EXPORT_SYMBOL(vme_master_free); - -/* - * Request a DMA controller with specific attributes, return some unique - * identifier. - */ -struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) -{ - struct vme_bridge *bridge; - struct list_head *dma_pos = NULL; - struct vme_dma_resource *allocated_ctrlr = NULL; - struct vme_dma_resource *dma_ctrlr = NULL; - struct vme_resource *resource = NULL; - - /* XXX Not checking resource attributes */ - printk(KERN_ERR "No VME resource Attribute tests done\n"); - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through DMA resources */ - list_for_each(dma_pos, &bridge->dma_resources) { - dma_ctrlr = list_entry(dma_pos, - struct vme_dma_resource, list); - - if (dma_ctrlr == NULL) { - printk(KERN_ERR "Registered NULL DMA resource\n"); - continue; - } - - /* Find an unlocked and compatible controller */ - mutex_lock(&dma_ctrlr->mtx); - if (((dma_ctrlr->route_attr & route) == route) && - (dma_ctrlr->locked == 0)) { - - dma_ctrlr->locked = 1; - mutex_unlock(&dma_ctrlr->mtx); - allocated_ctrlr = dma_ctrlr; - break; - } - mutex_unlock(&dma_ctrlr->mtx); - } - - /* Check to see if we found a resource */ - if (allocated_ctrlr == NULL) - goto err_ctrlr; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_WARNING "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_DMA; - resource->entry = &allocated_ctrlr->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&dma_ctrlr->mtx); - dma_ctrlr->locked = 0; - mutex_unlock(&dma_ctrlr->mtx); -err_ctrlr: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_dma_request); - -/* - * Start new list - */ -struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) -{ - struct vme_dma_resource *ctrlr; - struct vme_dma_list *dma_list; - - if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); - return NULL; - } - - ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - - dma_list = kmalloc(sizeof(struct vme_dma_list), GFP_KERNEL); - if (dma_list == NULL) { - printk(KERN_ERR "Unable to allocate memory for new dma list\n"); - return NULL; - } - INIT_LIST_HEAD(&dma_list->entries); - dma_list->parent = ctrlr; - mutex_init(&dma_list->mtx); - - return dma_list; -} -EXPORT_SYMBOL(vme_new_dma_list); - -/* - * Create "Pattern" type attributes - */ -struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type) -{ - struct vme_dma_attr *attributes; - struct vme_dma_pattern *pattern_attr; - - attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); - goto err_attr; - } - - pattern_attr = kmalloc(sizeof(struct vme_dma_pattern), GFP_KERNEL); - if (pattern_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pattern " - "attributes\n"); - goto err_pat; - } - - attributes->type = VME_DMA_PATTERN; - attributes->private = (void *)pattern_attr; - - pattern_attr->pattern = pattern; - pattern_attr->type = type; - - return attributes; - -err_pat: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_pattern_attribute); - -/* - * Create "PCI" type attributes - */ -struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) -{ - struct vme_dma_attr *attributes; - struct vme_dma_pci *pci_attr; - - /* XXX Run some sanity checks here */ - - attributes = kmalloc(sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); - goto err_attr; - } - - pci_attr = kmalloc(sizeof(struct vme_dma_pci), GFP_KERNEL); - if (pci_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for pci " - "attributes\n"); - goto err_pci; - } - - - - attributes->type = VME_DMA_PCI; - attributes->private = (void *)pci_attr; - - pci_attr->address = address; - - return attributes; - -err_pci: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_pci_attribute); - -/* - * Create "VME" type attributes - */ -struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, - u32 aspace, u32 cycle, u32 dwidth) -{ - struct vme_dma_attr *attributes; - struct vme_dma_vme *vme_attr; - - attributes = kmalloc( - sizeof(struct vme_dma_attr), GFP_KERNEL); - if (attributes == NULL) { - printk(KERN_ERR "Unable to allocate memory for attributes " - "structure\n"); - goto err_attr; - } - - vme_attr = kmalloc(sizeof(struct vme_dma_vme), GFP_KERNEL); - if (vme_attr == NULL) { - printk(KERN_ERR "Unable to allocate memory for vme " - "attributes\n"); - goto err_vme; - } - - attributes->type = VME_DMA_VME; - attributes->private = (void *)vme_attr; - - vme_attr->address = address; - vme_attr->aspace = aspace; - vme_attr->cycle = cycle; - vme_attr->dwidth = dwidth; - - return attributes; - -err_vme: - kfree(attributes); -err_attr: - return NULL; -} -EXPORT_SYMBOL(vme_dma_vme_attribute); - -/* - * Free attribute - */ -void vme_dma_free_attribute(struct vme_dma_attr *attributes) -{ - kfree(attributes->private); - kfree(attributes); -} -EXPORT_SYMBOL(vme_dma_free_attribute); - -int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, - struct vme_dma_attr *dest, size_t count) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_add == NULL) { - printk(KERN_WARNING "Link List DMA generation not supported\n"); - return -EINVAL; - } - - if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List already submitted\n"); - return -EINVAL; - } - - retval = bridge->dma_list_add(list, src, dest, count); - - mutex_unlock(&list->mtx); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_add); - -int vme_dma_list_exec(struct vme_dma_list *list) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_exec == NULL) { - printk(KERN_ERR "Link List DMA execution not supported\n"); - return -EINVAL; - } - - mutex_lock(&list->mtx); - - retval = bridge->dma_list_exec(list); - - mutex_unlock(&list->mtx); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_exec); - -int vme_dma_list_free(struct vme_dma_list *list) -{ - struct vme_bridge *bridge = list->parent->parent; - int retval; - - if (bridge->dma_list_empty == NULL) { - printk(KERN_WARNING "Emptying of Link Lists not supported\n"); - return -EINVAL; - } - - if (!mutex_trylock(&list->mtx)) { - printk(KERN_ERR "Link List in use\n"); - return -EINVAL; - } - - /* - * Empty out all of the entries from the dma list. We need to go to the - * low level driver as dma entries are driver specific. - */ - retval = bridge->dma_list_empty(list); - if (retval) { - printk(KERN_ERR "Unable to empty link-list entries\n"); - mutex_unlock(&list->mtx); - return retval; - } - mutex_unlock(&list->mtx); - kfree(list); - - return retval; -} -EXPORT_SYMBOL(vme_dma_list_free); - -int vme_dma_free(struct vme_resource *resource) -{ - struct vme_dma_resource *ctrlr; - - if (resource->type != VME_DMA) { - printk(KERN_ERR "Not a DMA resource\n"); - return -EINVAL; - } - - ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - - if (!mutex_trylock(&ctrlr->mtx)) { - printk(KERN_ERR "Resource busy, can't free\n"); - return -EBUSY; - } - - if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) { - printk(KERN_WARNING "Resource still processing transfers\n"); - mutex_unlock(&ctrlr->mtx); - return -EBUSY; - } - - ctrlr->locked = 0; - - mutex_unlock(&ctrlr->mtx); - - return 0; -} -EXPORT_SYMBOL(vme_dma_free); - -void vme_irq_handler(struct vme_bridge *bridge, int level, int statid) -{ - void (*call)(int, int, void *); - void *priv_data; - - call = bridge->irq[level - 1].callback[statid].func; - priv_data = bridge->irq[level - 1].callback[statid].priv_data; - - if (call != NULL) - call(level, statid, priv_data); - else - printk(KERN_WARNING "Spurilous VME interrupt, level:%x, " - "vector:%x\n", level, statid); -} -EXPORT_SYMBOL(vme_irq_handler); - -int vme_irq_request(struct vme_dev *vdev, int level, int statid, - void (*callback)(int, int, void *), - void *priv_data) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); - return -EINVAL; - } - - if (bridge->irq_set == NULL) { - printk(KERN_ERR "Configuring interrupts not supported\n"); - return -EINVAL; - } - - mutex_lock(&bridge->irq_mtx); - - if (bridge->irq[level - 1].callback[statid].func) { - mutex_unlock(&bridge->irq_mtx); - printk(KERN_WARNING "VME Interrupt already taken\n"); - return -EBUSY; - } - - bridge->irq[level - 1].count++; - bridge->irq[level - 1].callback[statid].priv_data = priv_data; - bridge->irq[level - 1].callback[statid].func = callback; - - /* Enable IRQ level */ - bridge->irq_set(bridge, level, 1, 1); - - mutex_unlock(&bridge->irq_mtx); - - return 0; -} -EXPORT_SYMBOL(vme_irq_request); - -void vme_irq_free(struct vme_dev *vdev, int level, int statid) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_ERR "Invalid interrupt level\n"); - return; - } - - if (bridge->irq_set == NULL) { - printk(KERN_ERR "Configuring interrupts not supported\n"); - return; - } - - mutex_lock(&bridge->irq_mtx); - - bridge->irq[level - 1].count--; - - /* Disable IRQ level if no more interrupts attached at this level*/ - if (bridge->irq[level - 1].count == 0) - bridge->irq_set(bridge, level, 0, 1); - - bridge->irq[level - 1].callback[statid].func = NULL; - bridge->irq[level - 1].callback[statid].priv_data = NULL; - - mutex_unlock(&bridge->irq_mtx); -} -EXPORT_SYMBOL(vme_irq_free); - -int vme_irq_generate(struct vme_dev *vdev, int level, int statid) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if ((level < 1) || (level > 7)) { - printk(KERN_WARNING "Invalid interrupt level\n"); - return -EINVAL; - } - - if (bridge->irq_generate == NULL) { - printk(KERN_WARNING "Interrupt generation not supported\n"); - return -EINVAL; - } - - return bridge->irq_generate(bridge, level, statid); -} -EXPORT_SYMBOL(vme_irq_generate); - -/* - * Request the location monitor, return resource or NULL - */ -struct vme_resource *vme_lm_request(struct vme_dev *vdev) -{ - struct vme_bridge *bridge; - struct list_head *lm_pos = NULL; - struct vme_lm_resource *allocated_lm = NULL; - struct vme_lm_resource *lm = NULL; - struct vme_resource *resource = NULL; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - goto err_bus; - } - - /* Loop through DMA resources */ - list_for_each(lm_pos, &bridge->lm_resources) { - lm = list_entry(lm_pos, - struct vme_lm_resource, list); - - if (lm == NULL) { - printk(KERN_ERR "Registered NULL Location Monitor " - "resource\n"); - continue; - } - - /* Find an unlocked controller */ - mutex_lock(&lm->mtx); - if (lm->locked == 0) { - lm->locked = 1; - mutex_unlock(&lm->mtx); - allocated_lm = lm; - break; - } - mutex_unlock(&lm->mtx); - } - - /* Check to see if we found a resource */ - if (allocated_lm == NULL) - goto err_lm; - - resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL); - if (resource == NULL) { - printk(KERN_ERR "Unable to allocate resource structure\n"); - goto err_alloc; - } - resource->type = VME_LM; - resource->entry = &allocated_lm->list; - - return resource; - -err_alloc: - /* Unlock image */ - mutex_lock(&lm->mtx); - lm->locked = 0; - mutex_unlock(&lm->mtx); -err_lm: -err_bus: - return NULL; -} -EXPORT_SYMBOL(vme_lm_request); - -int vme_lm_count(struct vme_resource *resource) -{ - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - return lm->monitors; -} -EXPORT_SYMBOL(vme_lm_count); - -int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, - u32 aspace, u32 cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_set == NULL) { - printk(KERN_ERR "vme_lm_set not supported\n"); - return -EINVAL; - } - - return bridge->lm_set(lm, lm_base, aspace, cycle); -} -EXPORT_SYMBOL(vme_lm_set); - -int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base, - u32 *aspace, u32 *cycle) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_get == NULL) { - printk(KERN_ERR "vme_lm_get not supported\n"); - return -EINVAL; - } - - return bridge->lm_get(lm, lm_base, aspace, cycle); -} -EXPORT_SYMBOL(vme_lm_get); - -int vme_lm_attach(struct vme_resource *resource, int monitor, - void (*callback)(int)) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_attach == NULL) { - printk(KERN_ERR "vme_lm_attach not supported\n"); - return -EINVAL; - } - - return bridge->lm_attach(lm, monitor, callback); -} -EXPORT_SYMBOL(vme_lm_attach); - -int vme_lm_detach(struct vme_resource *resource, int monitor) -{ - struct vme_bridge *bridge = find_bridge(resource); - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return -EINVAL; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - if (bridge->lm_detach == NULL) { - printk(KERN_ERR "vme_lm_detach not supported\n"); - return -EINVAL; - } - - return bridge->lm_detach(lm, monitor); -} -EXPORT_SYMBOL(vme_lm_detach); - -void vme_lm_free(struct vme_resource *resource) -{ - struct vme_lm_resource *lm; - - if (resource->type != VME_LM) { - printk(KERN_ERR "Not a Location Monitor resource\n"); - return; - } - - lm = list_entry(resource->entry, struct vme_lm_resource, list); - - mutex_lock(&lm->mtx); - - /* XXX - * Check to see that there aren't any callbacks still attached, if - * there are we should probably be detaching them! - */ - - lm->locked = 0; - - mutex_unlock(&lm->mtx); - - kfree(resource); -} -EXPORT_SYMBOL(vme_lm_free); - -int vme_slot_get(struct vme_dev *vdev) -{ - struct vme_bridge *bridge; - - bridge = vdev->bridge; - if (bridge == NULL) { - printk(KERN_ERR "Can't find VME bus\n"); - return -EINVAL; - } - - if (bridge->slot_get == NULL) { - printk(KERN_WARNING "vme_slot_get not supported\n"); - return -EINVAL; - } - - return bridge->slot_get(bridge); -} -EXPORT_SYMBOL(vme_slot_get); - - -/* - Bridge Registration --------------------------------------------------- */ - -static void vme_dev_release(struct device *dev) -{ - kfree(dev_to_vme_dev(dev)); -} - -int vme_register_bridge(struct vme_bridge *bridge) -{ - int i; - int ret = -1; - - mutex_lock(&vme_buses_lock); - for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { - if ((vme_bus_numbers & (1 << i)) == 0) { - vme_bus_numbers |= (1 << i); - bridge->num = i; - INIT_LIST_HEAD(&bridge->devices); - list_add_tail(&bridge->bus_list, &vme_bus_list); - ret = 0; - break; - } - } - mutex_unlock(&vme_buses_lock); - - return ret; -} -EXPORT_SYMBOL(vme_register_bridge); - -void vme_unregister_bridge(struct vme_bridge *bridge) -{ - struct vme_dev *vdev; - struct vme_dev *tmp; - - mutex_lock(&vme_buses_lock); - vme_bus_numbers &= ~(1 << bridge->num); - list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) { - list_del(&vdev->drv_list); - list_del(&vdev->bridge_list); - device_unregister(&vdev->dev); - } - list_del(&bridge->bus_list); - mutex_unlock(&vme_buses_lock); -} -EXPORT_SYMBOL(vme_unregister_bridge); - -/* - Driver Registration --------------------------------------------------- */ - -static int __vme_register_driver_bus(struct vme_driver *drv, - struct vme_bridge *bridge, unsigned int ndevs) -{ - int err; - unsigned int i; - struct vme_dev *vdev; - struct vme_dev *tmp; - - for (i = 0; i < ndevs; i++) { - vdev = kzalloc(sizeof(struct vme_dev), GFP_KERNEL); - if (!vdev) { - err = -ENOMEM; - goto err_devalloc; - } - vdev->num = i; - vdev->bridge = bridge; - vdev->dev.platform_data = drv; - vdev->dev.release = vme_dev_release; - vdev->dev.parent = bridge->parent; - vdev->dev.bus = &vme_bus_type; - dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num, - vdev->num); - - err = device_register(&vdev->dev); - if (err) - goto err_reg; - - if (vdev->dev.platform_data) { - list_add_tail(&vdev->drv_list, &drv->devices); - list_add_tail(&vdev->bridge_list, &bridge->devices); - } else - device_unregister(&vdev->dev); - } - return 0; - -err_reg: - kfree(vdev); -err_devalloc: - list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) { - list_del(&vdev->drv_list); - list_del(&vdev->bridge_list); - device_unregister(&vdev->dev); - } - return err; -} - -static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs) -{ - struct vme_bridge *bridge; - int err = 0; - - mutex_lock(&vme_buses_lock); - list_for_each_entry(bridge, &vme_bus_list, bus_list) { - /* - * This cannot cause trouble as we already have vme_buses_lock - * and if the bridge is removed, it will have to go through - * vme_unregister_bridge() to do it (which calls remove() on - * the bridge which in turn tries to acquire vme_buses_lock and - * will have to wait). - */ - err = __vme_register_driver_bus(drv, bridge, ndevs); - if (err) - break; - } - mutex_unlock(&vme_buses_lock); - return err; -} - -int vme_register_driver(struct vme_driver *drv, unsigned int ndevs) -{ - int err; - - drv->driver.name = drv->name; - drv->driver.bus = &vme_bus_type; - INIT_LIST_HEAD(&drv->devices); - - err = driver_register(&drv->driver); - if (err) - return err; - - err = __vme_register_driver(drv, ndevs); - if (err) - driver_unregister(&drv->driver); - - return err; -} -EXPORT_SYMBOL(vme_register_driver); - -void vme_unregister_driver(struct vme_driver *drv) -{ - struct vme_dev *dev, *dev_tmp; - - mutex_lock(&vme_buses_lock); - list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) { - list_del(&dev->drv_list); - list_del(&dev->bridge_list); - device_unregister(&dev->dev); - } - mutex_unlock(&vme_buses_lock); - - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(vme_unregister_driver); - -/* - Bus Registration ------------------------------------------------------ */ - -static int vme_bus_match(struct device *dev, struct device_driver *drv) -{ - struct vme_driver *vme_drv; - - vme_drv = container_of(drv, struct vme_driver, driver); - - if (dev->platform_data == vme_drv) { - struct vme_dev *vdev = dev_to_vme_dev(dev); - - if (vme_drv->match && vme_drv->match(vdev)) - return 1; - - dev->platform_data = NULL; - } - return 0; -} - -static int vme_bus_probe(struct device *dev) -{ - int retval = -ENODEV; - struct vme_driver *driver; - struct vme_dev *vdev = dev_to_vme_dev(dev); - - driver = dev->platform_data; - - if (driver->probe != NULL) - retval = driver->probe(vdev); - - return retval; -} - -static int vme_bus_remove(struct device *dev) -{ - int retval = -ENODEV; - struct vme_driver *driver; - struct vme_dev *vdev = dev_to_vme_dev(dev); - - driver = dev->platform_data; - - if (driver->remove != NULL) - retval = driver->remove(vdev); - - return retval; -} - -struct bus_type vme_bus_type = { - .name = "vme", - .match = vme_bus_match, - .probe = vme_bus_probe, - .remove = vme_bus_remove, -}; -EXPORT_SYMBOL(vme_bus_type); - -static int __init vme_init(void) -{ - return bus_register(&vme_bus_type); -} - -static void __exit vme_exit(void) -{ - bus_unregister(&vme_bus_type); -} - -MODULE_DESCRIPTION("VME bridge driver framework"); -MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com"); -MODULE_LICENSE("GPL"); - -module_init(vme_init); -module_exit(vme_exit); diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h deleted file mode 100644 index c9d65bf..0000000 --- a/drivers/staging/vme/vme.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _VME_H_ -#define _VME_H_ - -/* Resource Type */ -enum vme_resource_type { - VME_MASTER, - VME_SLAVE, - VME_DMA, - VME_LM -}; - -/* VME Address Spaces */ -#define VME_A16 0x1 -#define VME_A24 0x2 -#define VME_A32 0x4 -#define VME_A64 0x8 -#define VME_CRCSR 0x10 -#define VME_USER1 0x20 -#define VME_USER2 0x40 -#define VME_USER3 0x80 -#define VME_USER4 0x100 - -#define VME_A16_MAX 0x10000ULL -#define VME_A24_MAX 0x1000000ULL -#define VME_A32_MAX 0x100000000ULL -#define VME_A64_MAX 0x10000000000000000ULL -#define VME_CRCSR_MAX 0x1000000ULL - - -/* VME Cycle Types */ -#define VME_SCT 0x1 -#define VME_BLT 0x2 -#define VME_MBLT 0x4 -#define VME_2eVME 0x8 -#define VME_2eSST 0x10 -#define VME_2eSSTB 0x20 - -#define VME_2eSST160 0x100 -#define VME_2eSST267 0x200 -#define VME_2eSST320 0x400 - -#define VME_SUPER 0x1000 -#define VME_USER 0x2000 -#define VME_PROG 0x4000 -#define VME_DATA 0x8000 - -/* VME Data Widths */ -#define VME_D8 0x1 -#define VME_D16 0x2 -#define VME_D32 0x4 -#define VME_D64 0x8 - -/* Arbitration Scheduling Modes */ -#define VME_R_ROBIN_MODE 0x1 -#define VME_PRIORITY_MODE 0x2 - -#define VME_DMA_PATTERN (1<<0) -#define VME_DMA_PCI (1<<1) -#define VME_DMA_VME (1<<2) - -#define VME_DMA_PATTERN_BYTE (1<<0) -#define VME_DMA_PATTERN_WORD (1<<1) -#define VME_DMA_PATTERN_INCREMENT (1<<2) - -#define VME_DMA_VME_TO_MEM (1<<0) -#define VME_DMA_MEM_TO_VME (1<<1) -#define VME_DMA_VME_TO_VME (1<<2) -#define VME_DMA_MEM_TO_MEM (1<<3) -#define VME_DMA_PATTERN_TO_VME (1<<4) -#define VME_DMA_PATTERN_TO_MEM (1<<5) - -struct vme_dma_attr { - u32 type; - void *private; -}; - -struct vme_resource { - enum vme_resource_type type; - struct list_head *entry; -}; - -extern struct bus_type vme_bus_type; - -/* VME_MAX_BRIDGES comes from the type of vme_bus_numbers */ -#define VME_MAX_BRIDGES (sizeof(unsigned int)*8) -#define VME_MAX_SLOTS 32 - -#define VME_SLOT_CURRENT -1 -#define VME_SLOT_ALL -2 - -/** - * Structure representing a VME device - * @num: The device number - * @bridge: Pointer to the bridge device this device is on - * @dev: Internal device structure - * @drv_list: List of devices (per driver) - * @bridge_list: List of devices (per bridge) - */ -struct vme_dev { - int num; - struct vme_bridge *bridge; - struct device dev; - struct list_head drv_list; - struct list_head bridge_list; -}; - -struct vme_driver { - struct list_head node; - const char *name; - int (*match)(struct vme_dev *); - int (*probe)(struct vme_dev *); - int (*remove)(struct vme_dev *); - void (*shutdown)(void); - struct device_driver driver; - struct list_head devices; -}; - -void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); -void vme_free_consistent(struct vme_resource *, size_t, void *, - dma_addr_t); - -size_t vme_get_size(struct vme_resource *); - -struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32); -int vme_slave_set(struct vme_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, u32, u32); -int vme_slave_get(struct vme_resource *, int *, unsigned long long *, - unsigned long long *, dma_addr_t *, u32 *, u32 *); -void vme_slave_free(struct vme_resource *); - -struct vme_resource *vme_master_request(struct vme_dev *, u32, u32, u32); -int vme_master_set(struct vme_resource *, int, unsigned long long, - unsigned long long, u32, u32, u32); -int vme_master_get(struct vme_resource *, int *, unsigned long long *, - unsigned long long *, u32 *, u32 *, u32 *); -ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); -ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); -unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, - unsigned int, loff_t); -void vme_master_free(struct vme_resource *); - -struct vme_resource *vme_dma_request(struct vme_dev *, u32); -struct vme_dma_list *vme_new_dma_list(struct vme_resource *); -struct vme_dma_attr *vme_dma_pattern_attribute(u32, u32); -struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); -struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, u32, u32, u32); -void vme_dma_free_attribute(struct vme_dma_attr *); -int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); -int vme_dma_list_exec(struct vme_dma_list *); -int vme_dma_list_free(struct vme_dma_list *); -int vme_dma_free(struct vme_resource *); - -int vme_irq_request(struct vme_dev *, int, int, - void (*callback)(int, int, void *), void *); -void vme_irq_free(struct vme_dev *, int, int); -int vme_irq_generate(struct vme_dev *, int, int); - -struct vme_resource *vme_lm_request(struct vme_dev *); -int vme_lm_count(struct vme_resource *); -int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32); -int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *); -int vme_lm_attach(struct vme_resource *, int, void (*callback)(int)); -int vme_lm_detach(struct vme_resource *, int); -void vme_lm_free(struct vme_resource *); - -int vme_slot_get(struct vme_dev *); - -int vme_register_driver(struct vme_driver *, unsigned int); -void vme_unregister_driver(struct vme_driver *); - - -#endif /* _VME_H_ */ - diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt deleted file mode 100644 index 856efa3..0000000 --- a/drivers/staging/vme/vme_api.txt +++ /dev/null @@ -1,396 +0,0 @@ - VME Device Driver API - ===================== - -Driver registration -=================== - -As with other subsystems within the Linux kernel, VME device drivers register -with the VME subsystem, typically called from the devices init routine. This is -achieved via a call to the following function: - - int vme_register_driver (struct vme_driver *driver); - -If driver registration is successful this function returns zero, if an error -occurred a negative error code will be returned. - -A pointer to a structure of type 'vme_driver' must be provided to the -registration function. The structure is as follows: - - struct vme_driver { - struct list_head node; - const char *name; - int (*match)(struct vme_dev *); - int (*probe)(struct vme_dev *); - int (*remove)(struct vme_dev *); - void (*shutdown)(void); - struct device_driver driver; - struct list_head devices; - unsigned int ndev; - }; - -At the minimum, the '.name', '.match' and '.probe' elements of this structure -should be correctly set. The '.name' element is a pointer to a string holding -the device driver's name. - -The '.match' function allows controlling the number of devices that need to -be registered. The match function should return 1 if a device should be -probed and 0 otherwise. This example match function (from vme_user.c) limits -the number of devices probed to one: - - #define USER_BUS_MAX 1 - ... - static int vme_user_match(struct vme_dev *vdev) - { - if (vdev->id.num >= USER_BUS_MAX) - return 0; - return 1; - } - -The '.probe' element should contain a pointer to the probe routine. The -probe routine is passed a 'struct vme_dev' pointer as an argument. The -'struct vme_dev' structure looks like the following: - - struct vme_dev { - int num; - struct vme_bridge *bridge; - struct device dev; - struct list_head drv_list; - struct list_head bridge_list; - }; - -Here, the 'num' field refers to the sequential device ID for this specific -driver. The bridge number (or bus number) can be accessed using -dev->bridge->num. - -A function is also provided to unregister the driver from the VME core and is -usually called from the device driver's exit routine: - - void vme_unregister_driver (struct vme_driver *driver); - - -Resource management -=================== - -Once a driver has registered with the VME core the provided match routine will -be called the number of times specified during the registration. If a match -succeeds, a non-zero value should be returned. A zero return value indicates -failure. For all successful matches, the probe routine of the corresponding -driver is called. The probe routine is passed a pointer to the devices -device structure. This pointer should be saved, it will be required for -requesting VME resources. - -The driver can request ownership of one or more master windows, slave windows -and/or dma channels. Rather than allowing the device driver to request a -specific window or DMA channel (which may be used by a different driver) this -driver allows a resource to be assigned based on the required attributes of the -driver in question: - - struct vme_resource * vme_master_request(struct vme_dev *dev, - u32 aspace, u32 cycle, u32 width); - - struct vme_resource * vme_slave_request(struct vme_dev *dev, u32 aspace, - u32 cycle); - - struct vme_resource *vme_dma_request(struct vme_dev *dev, u32 route); - -For slave windows these attributes are split into the VME address spaces that -need to be accessed in 'aspace' and VME bus cycle types required in 'cycle'. -Master windows add a further set of attributes in 'width' specifying the -required data transfer widths. These attributes are defined as bitmasks and as -such any combination of the attributes can be requested for a single window, -the core will assign a window that meets the requirements, returning a pointer -of type vme_resource that should be used to identify the allocated resource -when it is used. For DMA controllers, the request function requires the -potential direction of any transfers to be provided in the route attributes. -This is typically VME-to-MEM and/or MEM-to-VME, though some hardware can -support VME-to-VME and MEM-to-MEM transfers as well as test pattern generation. -If an unallocated window fitting the requirements can not be found a NULL -pointer will be returned. - -Functions are also provided to free window allocations once they are no longer -required. These functions should be passed the pointer to the resource provided -during resource allocation: - - void vme_master_free(struct vme_resource *res); - - void vme_slave_free(struct vme_resource *res); - - void vme_dma_free(struct vme_resource *res); - - -Master windows -============== - -Master windows provide access from the local processor[s] out onto the VME bus. -The number of windows available and the available access modes is dependent on -the underlying chipset. A window must be configured before it can be used. - - -Master window configuration ---------------------------- - -Once a master window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_master_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, u32 aspace, - u32 cycle, u32 width); - - int vme_master_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, u32 *aspace, - u32 *cycle, u32 *width); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Master window access --------------------- - -The following functions can be used to read from and write to configured master -windows. These functions return the number of bytes copied: - - ssize_t vme_master_read(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - - ssize_t vme_master_write(struct vme_resource *res, void *buf, - size_t count, loff_t offset); - -In addition to simple reads and writes, a function is provided to do a -read-modify-write transaction. This function returns the original value of the -VME bus location : - - unsigned int vme_master_rmw (struct vme_resource *res, - unsigned int mask, unsigned int compare, unsigned int swap, - loff_t offset); - -This functions by reading the offset, applying the mask. If the bits selected in -the mask match with the values of the corresponding bits in the compare field, -the value of swap is written the specified offset. - - -Slave windows -============= - -Slave windows provide devices on the VME bus access into mapped portions of the -local memory. The number of windows available and the access modes that can be -used is dependent on the underlying chipset. A window must be configured before -it can be used. - - -Slave window configuration --------------------------- - -Once a slave window has been assigned the following functions can be used to -configure it and retrieve the current settings: - - int vme_slave_set (struct vme_resource *res, int enabled, - unsigned long long base, unsigned long long size, - dma_addr_t mem, u32 aspace, u32 cycle); - - int vme_slave_get (struct vme_resource *res, int *enabled, - unsigned long long *base, unsigned long long *size, - dma_addr_t *mem, u32 *aspace, u32 *cycle); - -The address spaces, transfer widths and cycle types are the same as described -under resource management, however some of the options are mutually exclusive. -For example, only one address space may be specified. - -These functions return 0 on success or an error code should the call fail. - - -Slave window buffer allocation ------------------------------- - -Functions are provided to allow the user to allocate and free a contiguous -buffers which will be accessible by the VME bridge. These functions do not have -to be used, other methods can be used to allocate a buffer, though care must be -taken to ensure that they are contiguous and accessible by the VME bridge: - - void * vme_alloc_consistent(struct vme_resource *res, size_t size, - dma_addr_t *mem); - - void vme_free_consistent(struct vme_resource *res, size_t size, - void *virt, dma_addr_t mem); - - -Slave window access -------------------- - -Slave windows map local memory onto the VME bus, the standard methods for -accessing memory should be used. - - -DMA channels -============ - -The VME DMA transfer provides the ability to run link-list DMA transfers. The -API introduces the concept of DMA lists. Each DMA list is a link-list which can -be passed to a DMA controller. Multiple lists can be created, extended, -executed, reused and destroyed. - - -List Management ---------------- - -The following functions are provided to create and destroy DMA lists. Execution -of a list will not automatically destroy the list, thus enabling a list to be -reused for repetitive tasks: - - struct vme_dma_list *vme_new_dma_list(struct vme_resource *res); - - int vme_dma_list_free(struct vme_dma_list *list); - - -List Population ---------------- - -An item can be added to a list using the following function ( the source and -destination attributes need to be created before calling this function, this is -covered under "Transfer Attributes"): - - int vme_dma_list_add(struct vme_dma_list *list, - struct vme_dma_attr *src, struct vme_dma_attr *dest, - size_t count); - -NOTE: The detailed attributes of the transfers source and destination - are not checked until an entry is added to a DMA list, the request - for a DMA channel purely checks the directions in which the - controller is expected to transfer data. As a result it is - possible for this call to return an error, for example if the - source or destination is in an unsupported VME address space. - -Transfer Attributes -------------------- - -The attributes for the source and destination are handled separately from adding -an item to a list. This is due to the diverse attributes required for each type -of source and destination. There are functions to create attributes for PCI, VME -and pattern sources and destinations (where appropriate): - -Pattern source: - - struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); - -PCI source or destination: - - struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem); - -VME source or destination: - - struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base, - u32 aspace, u32 cycle, u32 width); - -The following function should be used to free an attribute: - - void vme_dma_free_attribute(struct vme_dma_attr *attr); - - -List Execution --------------- - -The following function queues a list for execution. The function will return -once the list has been executed: - - int vme_dma_list_exec(struct vme_dma_list *list); - - -Interrupts -========== - -The VME API provides functions to attach and detach callbacks to specific VME -level and status ID combinations and for the generation of VME interrupts with -specific VME level and status IDs. - - -Attaching Interrupt Handlers ----------------------------- - -The following functions can be used to attach and free a specific VME level and -status ID combination. Any given combination can only be assigned a single -callback function. A void pointer parameter is provided, the value of which is -passed to the callback function, the use of this pointer is user undefined: - - int vme_irq_request(struct vme_dev *dev, int level, int statid, - void (*callback)(int, int, void *), void *priv); - - void vme_irq_free(struct vme_dev *dev, int level, int statid); - -The callback parameters are as follows. Care must be taken in writing a callback -function, callback functions run in interrupt context: - - void callback(int level, int statid, void *priv); - - -Interrupt Generation --------------------- - -The following function can be used to generate a VME interrupt at a given VME -level and VME status ID: - - int vme_irq_generate(struct vme_dev *dev, int level, int statid); - - -Location monitors -================= - -The VME API provides the following functionality to configure the location -monitor. - - -Location Monitor Management ---------------------------- - -The following functions are provided to request the use of a block of location -monitors and to free them after they are no longer required: - - struct vme_resource * vme_lm_request(struct vme_dev *dev); - - void vme_lm_free(struct vme_resource * res); - -Each block may provide a number of location monitors, monitoring adjacent -locations. The following function can be used to determine how many locations -are provided: - - int vme_lm_count(struct vme_resource * res); - - -Location Monitor Configuration ------------------------------- - -Once a bank of location monitors has been allocated, the following functions -are provided to configure the location and mode of the location monitor: - - int vme_lm_set(struct vme_resource *res, unsigned long long base, - u32 aspace, u32 cycle); - - int vme_lm_get(struct vme_resource *res, unsigned long long *base, - u32 *aspace, u32 *cycle); - - -Location Monitor Use --------------------- - -The following functions allow a callback to be attached and detached from each -location monitor location. Each location monitor can monitor a number of -adjacent locations: - - int vme_lm_attach(struct vme_resource *res, int num, - void (*callback)(int)); - - int vme_lm_detach(struct vme_resource *res, int num); - -The callback function is declared as follows. - - void callback(int num); - - -Slot Detection -============== - -This function returns the slot ID of the provided bridge. - - int vme_slot_get(struct vme_dev *dev); diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h deleted file mode 100644 index 934949a..0000000 --- a/drivers/staging/vme/vme_bridge.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef _VME_BRIDGE_H_ -#define _VME_BRIDGE_H_ - -#define VME_CRCSR_BUF_SIZE (508*1024) -/* - * Resource structures - */ -struct vme_master_resource { - struct list_head list; - struct vme_bridge *parent; - /* - * We are likely to need to access the VME bus in interrupt context, so - * protect master routines with a spinlock rather than a mutex. - */ - spinlock_t lock; - int locked; - int number; - u32 address_attr; - u32 cycle_attr; - u32 width_attr; - struct resource bus_resource; - void __iomem *kern_base; -}; - -struct vme_slave_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - u32 address_attr; - u32 cycle_attr; -}; - -struct vme_dma_pattern { - u32 pattern; - u32 type; -}; - -struct vme_dma_pci { - dma_addr_t address; -}; - -struct vme_dma_vme { - unsigned long long address; - u32 aspace; - u32 cycle; - u32 dwidth; -}; - -struct vme_dma_list { - struct list_head list; - struct vme_dma_resource *parent; - struct list_head entries; - struct mutex mtx; -}; - -struct vme_dma_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - struct list_head pending; - struct list_head running; - u32 route_attr; -}; - -struct vme_lm_resource { - struct list_head list; - struct vme_bridge *parent; - struct mutex mtx; - int locked; - int number; - int monitors; -}; - -struct vme_bus_error { - struct list_head list; - unsigned long long address; - u32 attributes; -}; - -struct vme_callback { - void (*func)(int, int, void*); - void *priv_data; -}; - -struct vme_irq { - int count; - struct vme_callback callback[255]; -}; - -/* Allow 16 characters for name (including null character) */ -#define VMENAMSIZ 16 - -/* This structure stores all the information about one bridge - * The structure should be dynamically allocated by the driver and one instance - * of the structure should be present for each VME chip present in the system. - */ -struct vme_bridge { - char name[VMENAMSIZ]; - int num; - struct list_head master_resources; - struct list_head slave_resources; - struct list_head dma_resources; - struct list_head lm_resources; - - struct list_head vme_errors; /* List for errors generated on VME */ - struct list_head devices; /* List of devices on this bridge */ - - /* Bridge Info - XXX Move to private structure? */ - struct device *parent; /* Parent device (eg. pdev->dev for PCI) */ - void *driver_priv; /* Private pointer for the bridge driver */ - struct list_head bus_list; /* list of VME buses */ - - /* Interrupt callbacks */ - struct vme_irq irq[7]; - /* Locking for VME irq callback configuration */ - struct mutex irq_mtx; - - /* Slave Functions */ - int (*slave_get) (struct vme_slave_resource *, int *, - unsigned long long *, unsigned long long *, dma_addr_t *, - u32 *, u32 *); - int (*slave_set) (struct vme_slave_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, u32, u32); - - /* Master Functions */ - int (*master_get) (struct vme_master_resource *, int *, - unsigned long long *, unsigned long long *, u32 *, u32 *, - u32 *); - int (*master_set) (struct vme_master_resource *, int, - unsigned long long, unsigned long long, u32, u32, u32); - ssize_t (*master_read) (struct vme_master_resource *, void *, size_t, - loff_t); - ssize_t (*master_write) (struct vme_master_resource *, void *, size_t, - loff_t); - unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int, - unsigned int, unsigned int, loff_t); - - /* DMA Functions */ - int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); - int (*dma_list_exec) (struct vme_dma_list *); - int (*dma_list_empty) (struct vme_dma_list *); - - /* Interrupt Functions */ - void (*irq_set) (struct vme_bridge *, int, int, int); - int (*irq_generate) (struct vme_bridge *, int, int); - - /* Location monitor functions */ - int (*lm_set) (struct vme_lm_resource *, unsigned long long, u32, u32); - int (*lm_get) (struct vme_lm_resource *, unsigned long long *, u32 *, - u32 *); - int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int)); - int (*lm_detach) (struct vme_lm_resource *, int); - - /* CR/CSR space functions */ - int (*slot_get) (struct vme_bridge *); - - /* Bridge parent interface */ - void *(*alloc_consistent)(struct device *dev, size_t size, - dma_addr_t *dma); - void (*free_consistent)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma); -}; - -void vme_irq_handler(struct vme_bridge *, int, int); - -int vme_register_bridge(struct vme_bridge *); -void vme_unregister_bridge(struct vme_bridge *); - -#endif /* _VME_BRIDGE_H_ */ diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 61ac46f..0afb9fe 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -148,7 +148,7 @@ WPA_ParseRSN ( { j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); - for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(unsigned char)); i++) { + for(i = 0; (i < pRSN->wPKCount) && (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) pBSSList->abyPKType[j++] = WPA_NONE; @@ -180,7 +180,7 @@ WPA_ParseRSN ( j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); - for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(unsigned char)); i++) { + for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index c0edf97..e4bdf2a 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -452,7 +452,7 @@ RXbBulkInProcessData ( } } - if (!is_multicast_ether_addr(pMACHeader->abyAddr1) && !is_broadcast_ether_addr(pMACHeader->abyAddr1)) { + if (!is_multicast_ether_addr(pMACHeader->abyAddr1)) { if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) { pDevice->s802_11Counter.FrameDuplicateCount++; return FALSE; diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c index d59456c..5b9a84f 100644 --- a/drivers/staging/vt6656/ioctl.c +++ b/drivers/staging/vt6656/ioctl.c @@ -90,18 +90,17 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) spin_lock_irq(&pDevice->lock); if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0) - BSSvClearBSSList((void *)pDevice, FALSE); + BSSvClearBSSList(pDevice, FALSE); else - BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); + BSSvClearBSSList(pDevice, pDevice->bLinkPass); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n"); if (pItemSSID->len != 0) - bScheduleCommand((void *)pDevice, - WLAN_CMD_BSSID_SCAN, + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID); else - bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -150,6 +149,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } } break; + case WLAN_CMD_BSS_JOIN: if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) { result = -EFAULT; @@ -190,10 +190,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); pMgmt->eCurrState = WMAC_STATE_IDLE; - bScheduleCommand((void *) pDevice, - WLAN_CMD_BSSID_SCAN, + bScheduleCommand(pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); - bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL); + bScheduleCommand(pDevice, WLAN_CMD_SSID, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -299,7 +298,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -EINVAL; break; } - pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC); + pList = kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), GFP_ATOMIC); if (pList == NULL) { result = -ENOMEM; break; @@ -313,7 +312,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval; pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo; RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm); - pList->sBSSIDList[ii].uRSSI = (unsigned int) ldBm; + pList->sBSSIDList[ii].uRSSI = (unsigned int)ldBm; /* pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI; */ memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN); pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID; @@ -356,6 +355,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) break; } break; + case WLAN_CMD_STOP_MAC: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n"); /* Todo xxxxxx */ @@ -534,7 +534,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); - bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); + bScheduleCommand(pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); break; @@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -ENOMEM; break; } - pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); + pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), GFP_ATOMIC); if (pNodeList == NULL) { result = -ENOMEM; break; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 763e028..ee5261a 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1257,9 +1257,7 @@ static void __devexit vt6656_disconnect(struct usb_interface *intf) } device_release_WPADEV(device); - - if (device->firmware) - release_firmware(device->firmware); + release_firmware(device->firmware); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c index 7dde3d6..b16d4dd 100644 --- a/drivers/staging/vt6656/wpa.c +++ b/drivers/staging/vt6656/wpa.c @@ -149,7 +149,7 @@ WPA_ParseRSN( j = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); for (i = 0; (i < pRSN->wPKCount) && - (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) { + (j < ARRAY_SIZE(pBSSList->abyPKType)); i++) { if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i) if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4)) pBSSList->abyPKType[j++] = WPA_NONE; @@ -182,7 +182,7 @@ WPA_ParseRSN( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); for (i = 0; (i < pIE_RSN_Auth->wAuthCount) && - (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) { + (j < ARRAY_SIZE(pBSSList->abyAuthType)); i++) { if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i) if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4)) pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X; diff --git a/drivers/staging/wlags49_h2/README.ubuntu b/drivers/staging/wlags49_h2/README.ubuntu index edee8b9..5f1cfb8f 100644 --- a/drivers/staging/wlags49_h2/README.ubuntu +++ b/drivers/staging/wlags49_h2/README.ubuntu @@ -87,7 +87,7 @@ The linux driver files (wl_xxxx.c) are changed in the following ways: -- Recovery actions added The major problem was the order in which calls can be made. The original -looks like a traditonal UNIX driver. To call an "ioctl" function you +looks like a traditional UNIX driver. To call an "ioctl" function you have to "open" the device first to get a handle and after "close" no "ioctl" function can be called anymore. With the 2.6 driver this all changed; the former ioctl functions are now called before "open" and diff --git a/drivers/staging/wlags49_h2/hcf.c b/drivers/staging/wlags49_h2/hcf.c index 5957c3a..366e4a4 100644 --- a/drivers/staging/wlags49_h2/hcf.c +++ b/drivers/staging/wlags49_h2/hcf.c @@ -2871,8 +2871,8 @@ or * The Assert validates the HCF assumption about Hermes implementation upon which the range of * Pseudo-RIDs is based. * Then the control fields up to the start of the 802.3 frame are read from the NIC into the lookahead buffer. -* The status field is converted to native Endianess. -* The length is, after implicit Endianess conversion if needed, and adjustment for the 14 bytes of the +* The status field is converted to native Endianness. +* The length is, after implicit Endianness conversion if needed, and adjustment for the 14 bytes of the * 802.3 MAC header, stored in IFB_RxLen. * In MAC Monitor mode, 802.11 control frames with a TOTAL length of 14 are received, so without this * length adjustment, IFB_RxLen could not be used to distinguish these frames from "no frame". @@ -2894,7 +2894,7 @@ or * - the Hermes reported Tunnel encapsulation or * - the Hermes reported 1042 Encapsulation and hcf_encap reports that the HCF would not have used * 1042 as the encapsulation mechanism -* Note that the first field of the RxFS in bufp has Native Endianess due to the conversion done by the +* Note that the first field of the RxFS in bufp has Native Endianness due to the conversion done by the * BE_PAR in get_frag. *36: The Type field is the only word kept (after moving) of the just read 8 bytes, it is moved to the * L-field. The original L-field and 6 byte SNAP header are discarded, so IFB_RxLen and buf_addr must @@ -3831,7 +3831,7 @@ get_fid( IFBP ifbp ) *.DESCRIPTION * process the single byte (if applicable) read by the previous get_frag and copy len (or len-1) bytes from * NIC to bufp. - * On a Big Endian platform, the parameter word_len controls the number of leading bytes whose endianess is + * On a Big Endian platform, the parameter word_len controls the number of leading bytes whose endianness is * converted (i.e. byte swapped) * * @@ -3980,7 +3980,7 @@ get_frag( IFBP ifbp, wci_bufp bufp, int len BE_PAR( int word_len ) ) * appropriate means on H-I: always * and on H-II if F/W supplier reflects a primary (i.e. only after an Hermes Reset or Init * command). - * QUESTION ;? !!!!!! should, For each of the above RIDs the Endianess is converted to native Endianess. + * QUESTION ;? !!!!!! should, For each of the above RIDs the Endianness is converted to native Endianness. * Only the return code of the first hcf_get_info is used. All hcf_get_info calls are made, regardless of * the success or failure of the 1st hcf_get_info. The assumptions are: * - if any call fails, they all fail, so remembering the result of the 1st call is adequate diff --git a/drivers/staging/wlags49_h2/hcf.h b/drivers/staging/wlags49_h2/hcf.h index 95527b5..68e2330 100644 --- a/drivers/staging/wlags49_h2/hcf.h +++ b/drivers/staging/wlags49_h2/hcf.h @@ -90,7 +90,7 @@ #define LOF(x) (sizeof(x)/sizeof(hcf_16)-1) -/* Endianess +/* Endianness * Little Endian (a.k.a. Intel), least significant byte first * Big Endian (a.k.a. Motorola), most significant byte first * @@ -101,7 +101,7 @@ */ /* To increase portability, use unsigned char and unsigned char * when accessing parts of larger - * types to convert their Endianess + * types to convert their Endianness */ #define CNV_END_SHORT(w) (hcf_16)( ((hcf_16)(w) & 0x00FF) << 8 | ((hcf_16)(w) & 0xFF00) >> 8 ) @@ -109,14 +109,14 @@ #if HCF_BIG_ENDIAN //******************************************** B I G E N D I A N ******************************************* -#define CNV_LITTLE_TO_SHORT(w) CNV_END_SHORT(w) // endianess conversion needed -#define CNV_BIG_TO_SHORT(w) (w) // no endianess conversion needed +#define CNV_LITTLE_TO_SHORT(w) CNV_END_SHORT(w) // endianness conversion needed +#define CNV_BIG_TO_SHORT(w) (w) // no endianness conversion needed #define CNV_LITTLE_TO_LONG(dw) CNV_END_LONG(dw) #define CNV_LONG_TO_LITTLE(dw) CNV_END_LONG(dw) #else //****************************************** L I T T L E E N D I A N **************************************** -#define CNV_LITTLE_TO_SHORT(w) (w) // no endianess conversion needed -#define CNV_BIG_TO_SHORT(w) CNV_END_SHORT(w) // endianess conversion needed +#define CNV_LITTLE_TO_SHORT(w) (w) // no endianness conversion needed +#define CNV_BIG_TO_SHORT(w) CNV_END_SHORT(w) // endianness conversion needed #define CNV_LITTLE_TO_LONG(dw) (dw) #define CNV_LONG_TO_LITTLE(dw) (dw) diff --git a/drivers/staging/wlags49_h2/mmd.c b/drivers/staging/wlags49_h2/mmd.c index c8f5210..7204a37 100644 --- a/drivers/staging/wlags49_h2/mmd.c +++ b/drivers/staging/wlags49_h2/mmd.c @@ -101,10 +101,10 @@ * supp address of the supplier specification * * Description: mmd_check_comp is a support routine to check the compatibility between an actor and a -* supplier. mmd_check_comp is independent of the endianess of the actp and supp structures. This is +* supplier. mmd_check_comp is independent of the endianness of the actp and supp structures. This is * achieved by checking the "bottom" or "role" fields of these structures. Since these fields are restricted * to a limited range, comparing the contents to a value with a known endian-ess gives a clue to their actual -* endianess. +* endianness. * *.DIAGRAM *1a: The role-field of the actor structure has a known non-zero, not "byte symmetric" value (namely @@ -114,16 +114,16 @@ * for a supplier. A supplier has always exactly 1 variant,top,bottom record with (officially, but see the * note below) each of these 3 values in the range 1 through 99, so one byte of the word value of variant, * top and bottom words is 0x00 and the other byte is non-zero. Whether the lowest address byte or the -* highest address byte is non-zero depends on the Endianess of the LTV. If and only if the word value of +* highest address byte is non-zero depends on the Endianness of the LTV. If and only if the word value of * bottom is less than 0x0100, the supplier is Native Endian. * NOTE: the variant field of the supplier structure can not be used for the Endian Detection Algorithm, * because a a zero-valued variant has been used as Controlled Deployment indication in the past. * Note: An actor may have multiple sets of variant,top,bottom records, including dummy sets with variant, -* top and bottom fields with a zero-value. As a consequence the endianess of the actor can not be determined +* top and bottom fields with a zero-value. As a consequence the endianness of the actor can not be determined * based on its variant,top,bottom values. * * Note: the L and T field of the structures are always in Native Endian format, so you can not draw -* conclusions concerning the Endianess of the structure based on these two fields. +* conclusions concerning the Endianness of the structure based on these two fields. * *1b/2b * The only purpose of the CFG_RANGE_SPEC_BYTE_STRCT is to give easy access to the non-zero byte of the word @@ -149,7 +149,7 @@ * * This is implemented as: * #if HCF_BIG_ENDIAN == 0 //platform is LE -* sup/act_endian becomes reverse of structure-endianess as determined in 1a/1b +* sup/act_endian becomes reverse of structure-endianness as determined in 1a/1b * #endif *6: Each of the actor variant-bottom-top records is checked against the (single) supplier variant-bottom-top * range till either an acceptable match is found or all actor records are tried. As explained above, due to diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 7084f41..7c7c77f 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -177,10 +177,9 @@ static void wl_adapter_detach(struct pcmcia_device *link) if (dev) { unregister_wlags_sysfs(dev); unregister_netdev(dev); + wl_device_dealloc(dev); } - wl_device_dealloc(dev); - DBG_LEAVE(DbgInfo); } /* wl_adapter_detach */ /*============================================================================*/ diff --git a/drivers/staging/wlags49_h2/wl_netdev.c b/drivers/staging/wlags49_h2/wl_netdev.c index 90820ff..824b852 100644 --- a/drivers/staging/wlags49_h2/wl_netdev.c +++ b/drivers/staging/wlags49_h2/wl_netdev.c @@ -1063,7 +1063,7 @@ void wl_multicast( struct net_device *dev ) #if DBG if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) { DBG_PRINT(" flags: %s%s%s\n", - ( dev->flags & IFF_PROMISC ) ? "Promiscous " : "", + ( dev->flags & IFF_PROMISC ) ? "Promiscuous " : "", ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "", ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" ); @@ -1510,8 +1510,11 @@ void wl_wds_device_alloc( struct wl_private *lp ) for( count = 0; count < NUM_WDS_PORTS; count++ ) { struct net_device *dev_wds = NULL; - dev_wds = kmalloc( sizeof( struct net_device ), GFP_KERNEL ); - memset( dev_wds, 0, sizeof( struct net_device )); + dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL); + if (!dev_wds) { + DBG_LEAVE(DbgInfo); + return; + } ether_setup( dev_wds ); diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 3df990c..0b31b01 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -524,6 +524,7 @@ int wl_pci_setup( struct pci_dev *pdev ) /* Make sure that space was allocated for our private adapter struct */ if( dev->priv == NULL ) { DBG_ERROR( DbgInfo, "Private adapter struct was not allocated!!!\n" ); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return -ENOMEM; } @@ -532,6 +533,7 @@ int wl_pci_setup( struct pci_dev *pdev ) /* Allocate DMA Descriptors */ if( wl_pci_dma_alloc( pdev, dev->priv ) < 0 ) { DBG_ERROR( DbgInfo, "Could not allocate DMA descriptor memory!!!\n" ); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return -ENOMEM; } @@ -561,6 +563,8 @@ int wl_pci_setup( struct pci_dev *pdev ) result = request_irq(dev->irq, wl_isr, SA_SHIRQ, dev->name, dev); if( result ) { DBG_WARNING( DbgInfo, "Could not register ISR!!!\n" ); + wl_remove(dev); + wl_device_dealloc(dev); DBG_LEAVE( DbgInfo ); return result; } diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index b8c96cf..0e49272 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -401,7 +401,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[0] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_2GHZ); } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value); @@ -409,7 +409,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC)) lp->brsc[1] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_5GHZ); } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) { DBG_TRACE(DbgInfo, "SSID, value: %s\n", value); @@ -556,7 +556,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[0] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_2GHZ); } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value); @@ -564,7 +564,7 @@ void translate_option(char *buffer, struct wl_private *lp) if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC)) lp->srsc[1] = value_convert; else - DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ); + DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_5GHZ); } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) { DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value); diff --git a/drivers/staging/wlags49_h2/wl_util.c b/drivers/staging/wlags49_h2/wl_util.c index f104e6f..404ec7d 100644 --- a/drivers/staging/wlags49_h2/wl_util.c +++ b/drivers/staging/wlags49_h2/wl_util.c @@ -98,8 +98,7 @@ ******************************************************************************/ /* A matrix which maps channels to frequencies */ -#define MAX_CHAN_FREQ_MAP_ENTRIES 50 -static const long chan_freq_list[][MAX_CHAN_FREQ_MAP_ENTRIES] = +static const long chan_freq_list[][2] = { {1,2412}, {2,2417}, @@ -846,7 +845,7 @@ int wl_is_a_valid_chan( int channel ) } /* Iterate through the matrix and retrieve the frequency */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][0] == channel ) { return 1; } @@ -884,7 +883,7 @@ int wl_is_a_valid_freq( long frequency ) /* Iterate through the matrix and retrieve the channel */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][1] == frequency ) { return 1; } @@ -927,7 +926,7 @@ long wl_get_freq_from_chan( int channel ) } /* Iterate through the matrix and retrieve the frequency */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][0] == channel ) { return chan_freq_list[i][1]; } @@ -965,7 +964,7 @@ int wl_get_chan_from_freq( long frequency ) /* Iterate through the matrix and retrieve the channel */ - for( i = 0; i < MAX_CHAN_FREQ_MAP_ENTRIES; i++ ) { + for( i = 0; i < ARRAY_SIZE(chan_freq_list); i++ ) { if( chan_freq_list[i][1] == frequency ) { return chan_freq_list[i][0]; } diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 4cd3ba5..8bc562b 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -332,6 +332,7 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, wlandevice_t *wlandev = dev->ml_priv; struct p80211msg_dot11req_scan msg1; struct p80211msg_dot11req_scan_results msg2; + struct cfg80211_bss *bss; int result; int err = 0; int numbss = 0; @@ -401,7 +402,7 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, ie_buf[1] = msg2.ssid.data.len; ie_len = ie_buf[1] + 2; memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len); - cfg80211_inform_bss(wiphy, + bss = cfg80211_inform_bss(wiphy, ieee80211_get_channel(wiphy, ieee80211_dsss_chan_to_freq(msg2.dschannel.data)), (const u8 *) &(msg2.bssid.data.data), msg2.timestamp.data, msg2.capinfo.data, @@ -411,6 +412,13 @@ int prism2_scan(struct wiphy *wiphy, struct net_device *dev, (msg2.signal.data - 65536) * 100, /* Conversion to signed type */ GFP_KERNEL ); + + if (!bss) { + err = -ENOMEM; + goto exit; + } + + cfg80211_put_bss(bss); } if (result) diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index c3bb05d..4efa9bc 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -380,8 +380,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) } count = (hw->scanresults->framelen - 3) / 32; - if (count > 32) - count = 32; + if (count > HFA384x_SCANRESULT_MAX) + count = HFA384x_SCANRESULT_MAX; if (req->bssindex.data >= count) { pr_debug("requested index (%d) out of range (%d)\n", diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index e828fd4..9c62aeb 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -12,9 +12,6 @@ #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) -#ifndef PCI_DEVICE_ID_XGI_41 -#define PCI_DEVICE_ID_XGI_41 0x041 -#endif #ifndef PCI_DEVICE_ID_XGI_42 #define PCI_DEVICE_ID_XGI_42 0x042 #endif @@ -82,177 +79,79 @@ static int XGIfb_tvplug = -1; /* TW: For ioctl XGIFB_GET_INFO */ /* XGIfb_info XGIfbinfo; */ -#define MD_XGI300 1 -#define MD_XGI315 2 +#define MD_XGI315 1 /* mode table */ static const struct _XGIbios_mode { - char name[15]; u8 mode_no; u16 vesa_mode_no_1; /* "XGI defined" VESA mode number */ u16 vesa_mode_no_2; /* Real VESA mode numbers */ u16 xres; u16 yres; u16 bpp; - u16 rate_idx; - u16 cols; - u16 rows; u8 chipset; } XGIbios_mode[] = { - {"320x240x16", 0x56, 0x0000, 0x0000, 320, 240, 16, 1, 40, 15, - MD_XGI315}, - {"320x480x8", 0x5A, 0x0000, 0x0000, 320, 480, 8, 1, 40, 30, - MD_XGI315}, /* TW: FSTN */ - {"320x480x16", 0x5B, 0x0000, 0x0000, 320, 480, 16, 1, 40, 30, - MD_XGI315}, /* TW: FSTN */ - {"640x480x8", 0x2E, 0x0101, 0x0101, 640, 480, 8, 1, 80, 30, - MD_XGI300|MD_XGI315}, - {"640x480x16", 0x44, 0x0111, 0x0111, 640, 480, 16, 1, 80, 30, - MD_XGI300|MD_XGI315}, - {"640x480x24", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, - MD_XGI300|MD_XGI315}, /* TW: That's for people who mix up color- - and fb depth */ - {"640x480x32", 0x62, 0x013a, 0x0112, 640, 480, 32, 1, 80, 30, - MD_XGI300|MD_XGI315}, - {"720x480x8", 0x31, 0x0000, 0x0000, 720, 480, 8, 1, 90, 30, - MD_XGI300|MD_XGI315}, - {"720x480x16", 0x33, 0x0000, 0x0000, 720, 480, 16, 1, 90, 30, - MD_XGI300|MD_XGI315}, - {"720x480x24", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, - MD_XGI300|MD_XGI315}, - {"720x480x32", 0x35, 0x0000, 0x0000, 720, 480, 32, 1, 90, 30, - MD_XGI300|MD_XGI315}, - {"720x576x8", 0x32, 0x0000, 0x0000, 720, 576, 8, 1, 90, 36, - MD_XGI300|MD_XGI315}, - {"720x576x16", 0x34, 0x0000, 0x0000, 720, 576, 16, 1, 90, 36, - MD_XGI300|MD_XGI315}, - {"720x576x24", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, - MD_XGI300|MD_XGI315}, - {"720x576x32", 0x36, 0x0000, 0x0000, 720, 576, 32, 1, 90, 36, - MD_XGI300|MD_XGI315}, - {"800x480x8", 0x70, 0x0000, 0x0000, 800, 480, 8, 1, 100, 30, - MD_XGI300|MD_XGI315}, - {"800x480x16", 0x7a, 0x0000, 0x0000, 800, 480, 16, 1, 100, 30, - MD_XGI300|MD_XGI315}, - {"800x480x24", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, - MD_XGI300|MD_XGI315}, - {"800x480x32", 0x76, 0x0000, 0x0000, 800, 480, 32, 1, 100, 30, - MD_XGI300|MD_XGI315}, - {"800x600x8", 0x30, 0x0103, 0x0103, 800, 600, 8, 1, 100, 37, - MD_XGI300|MD_XGI315}, -#define DEFAULT_MODE 20 /* index for 800x600x16 */ - {"800x600x16", 0x47, 0x0114, 0x0114, 800, 600, 16, 1, 100, 37, - MD_XGI300|MD_XGI315}, - {"800x600x24", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, - MD_XGI300|MD_XGI315}, - {"800x600x32", 0x63, 0x013b, 0x0115, 800, 600, 32, 1, 100, 37, - MD_XGI300|MD_XGI315}, - {"1024x576x8", 0x71, 0x0000, 0x0000, 1024, 576, 8, 1, 128, 36, - MD_XGI300|MD_XGI315}, - {"1024x576x16", 0x74, 0x0000, 0x0000, 1024, 576, 16, 1, 128, 36, - MD_XGI300|MD_XGI315}, - {"1024x576x24", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, - MD_XGI300|MD_XGI315}, - {"1024x576x32", 0x77, 0x0000, 0x0000, 1024, 576, 32, 1, 128, 36, - MD_XGI300|MD_XGI315}, - {"1024x600x8", 0x20, 0x0000, 0x0000, 1024, 600, 8, 1, 128, 37, - MD_XGI300 }, /* TW: 300 series only */ - {"1024x600x16", 0x21, 0x0000, 0x0000, 1024, 600, 16, 1, 128, 37, - MD_XGI300 }, - {"1024x600x24", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, - MD_XGI300 }, - {"1024x600x32", 0x22, 0x0000, 0x0000, 1024, 600, 32, 1, 128, 37, - MD_XGI300 }, - {"1024x768x8", 0x38, 0x0105, 0x0105, 1024, 768, 8, 1, 128, 48, - MD_XGI300|MD_XGI315}, - {"1024x768x16", 0x4A, 0x0117, 0x0117, 1024, 768, 16, 1, 128, 48, - MD_XGI300|MD_XGI315}, - {"1024x768x24", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, - MD_XGI300|MD_XGI315}, - {"1024x768x32", 0x64, 0x013c, 0x0118, 1024, 768, 32, 1, 128, 48, - MD_XGI300|MD_XGI315}, - {"1152x768x8", 0x23, 0x0000, 0x0000, 1152, 768, 8, 1, 144, 48, - MD_XGI300 }, /* TW: 300 series only */ - {"1152x768x16", 0x24, 0x0000, 0x0000, 1152, 768, 16, 1, 144, 48, - MD_XGI300 }, - {"1152x768x24", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, - MD_XGI300 }, - {"1152x768x32", 0x25, 0x0000, 0x0000, 1152, 768, 32, 1, 144, 48, - MD_XGI300 }, - {"1280x720x8", 0x79, 0x0000, 0x0000, 1280, 720, 8, 1, 160, 45, - MD_XGI300|MD_XGI315}, - {"1280x720x16", 0x75, 0x0000, 0x0000, 1280, 720, 16, 1, 160, 45, - MD_XGI300|MD_XGI315}, - {"1280x720x24", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, - MD_XGI300|MD_XGI315}, - {"1280x720x32", 0x78, 0x0000, 0x0000, 1280, 720, 32, 1, 160, 45, - MD_XGI300|MD_XGI315}, - {"1280x768x8", 0x23, 0x0000, 0x0000, 1280, 768, 8, 1, 160, 48, - MD_XGI315}, /* TW: 310/325 series only */ - {"1280x768x16", 0x24, 0x0000, 0x0000, 1280, 768, 16, 1, 160, 48, - MD_XGI315}, - {"1280x768x24", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, - MD_XGI315}, - {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, - MD_XGI315}, - {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, - MD_XGI300|MD_XGI315}, - {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, - MD_XGI300|MD_XGI315}, - {"1280x960x24", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, - MD_XGI300|MD_XGI315}, - {"1280x960x32", 0x7E, 0x0000, 0x0000, 1280, 960, 32, 1, 160, 60, - MD_XGI300|MD_XGI315}, - {"1280x1024x8", 0x3A, 0x0107, 0x0107, 1280, 1024, 8, 1, 160, 64, - MD_XGI300|MD_XGI315}, - {"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 1, 160, 64, - MD_XGI300|MD_XGI315}, - {"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, - MD_XGI300|MD_XGI315}, - {"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, - MD_XGI300|MD_XGI315}, - {"1400x1050x8", 0x26, 0x0000, 0x0000, 1400, 1050, 8, 1, 175, 65, - MD_XGI315}, /* TW: 310/325 series only */ - {"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65, - MD_XGI315}, - {"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, - MD_XGI315}, - {"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65, - MD_XGI315}, - {"1600x1200x8", 0x3C, 0x0130, 0x011c, 1600, 1200, 8, 1, 200, 75, - MD_XGI300|MD_XGI315}, - {"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, - MD_XGI300|MD_XGI315}, - {"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, - MD_XGI300|MD_XGI315}, - {"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, - MD_XGI300|MD_XGI315}, - {"1920x1440x8", 0x68, 0x013f, 0x0000, 1920, 1440, 8, 1, 240, 75, - MD_XGI300|MD_XGI315}, - {"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, - MD_XGI300|MD_XGI315}, - {"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, - MD_XGI300|MD_XGI315}, - {"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, - MD_XGI300|MD_XGI315}, - {"2048x1536x8", 0x6c, 0x0000, 0x0000, 2048, 1536, 8, 1, 256, 96, - MD_XGI315}, /* TW: 310/325 series only */ - {"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96, - MD_XGI315}, - {"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, - MD_XGI315}, - {"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96, - MD_XGI315}, - {"\0", 0x00, 0, 0, 0, 0, 0, 0, 0} + { 0x56, 0x0000, 0x0000, 320, 240, 16, MD_XGI315 }, + { 0x5A, 0x0000, 0x0000, 320, 480, 8, MD_XGI315 }, + { 0x5B, 0x0000, 0x0000, 320, 480, 16, MD_XGI315 }, + { 0x2E, 0x0101, 0x0101, 640, 480, 8, MD_XGI315 }, + { 0x44, 0x0111, 0x0111, 640, 480, 16, MD_XGI315 }, + { 0x62, 0x013a, 0x0112, 640, 480, 32, MD_XGI315 }, + { 0x31, 0x0000, 0x0000, 720, 480, 8, MD_XGI315 }, + { 0x33, 0x0000, 0x0000, 720, 480, 16, MD_XGI315 }, + { 0x35, 0x0000, 0x0000, 720, 480, 32, MD_XGI315 }, + { 0x32, 0x0000, 0x0000, 720, 576, 8, MD_XGI315 }, + { 0x34, 0x0000, 0x0000, 720, 576, 16, MD_XGI315 }, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, + { 0x36, 0x0000, 0x0000, 720, 576, 32, MD_XGI315 }, + { 0x70, 0x0000, 0x0000, 800, 480, 8, MD_XGI315 }, + { 0x7a, 0x0000, 0x0000, 800, 480, 16, MD_XGI315 }, + { 0x76, 0x0000, 0x0000, 800, 480, 32, MD_XGI315 }, + { 0x30, 0x0103, 0x0103, 800, 600, 8, MD_XGI315 }, +#define DEFAULT_MODE 17 /* index for 800x600x16 */ + { 0x47, 0x0114, 0x0114, 800, 600, 16, MD_XGI315 }, + { 0x63, 0x013b, 0x0115, 800, 600, 32, MD_XGI315 }, + { 0x71, 0x0000, 0x0000, 1024, 576, 8, MD_XGI315 }, + { 0x74, 0x0000, 0x0000, 1024, 576, 16, MD_XGI315 }, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, + { 0x77, 0x0000, 0x0000, 1024, 576, 32, MD_XGI315 }, + { 0x20, 0x0000, 0x0000, 1024, 600, 8, }, + { 0x21, 0x0000, 0x0000, 1024, 600, 16, }, + { 0x22, 0x0000, 0x0000, 1024, 600, 32, }, + { 0x38, 0x0105, 0x0105, 1024, 768, 8, MD_XGI315 }, + { 0x4A, 0x0117, 0x0117, 1024, 768, 16, MD_XGI315 }, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, + { 0x64, 0x013c, 0x0118, 1024, 768, 32, MD_XGI315 }, + { 0x23, 0x0000, 0x0000, 1152, 768, 8, }, + { 0x24, 0x0000, 0x0000, 1152, 768, 16, }, + { 0x25, 0x0000, 0x0000, 1152, 768, 32, }, + { 0x79, 0x0000, 0x0000, 1280, 720, 8, MD_XGI315 }, + { 0x75, 0x0000, 0x0000, 1280, 720, 16, MD_XGI315 }, + { 0x78, 0x0000, 0x0000, 1280, 720, 32, MD_XGI315 }, + { 0x23, 0x0000, 0x0000, 1280, 768, 8, MD_XGI315 }, + { 0x24, 0x0000, 0x0000, 1280, 768, 16, MD_XGI315 }, + { 0x25, 0x0000, 0x0000, 1280, 768, 32, MD_XGI315 }, + { 0x7C, 0x0000, 0x0000, 1280, 960, 8, MD_XGI315 }, + { 0x7D, 0x0000, 0x0000, 1280, 960, 16, MD_XGI315 }, + { 0x7E, 0x0000, 0x0000, 1280, 960, 32, MD_XGI315 }, + { 0x3A, 0x0107, 0x0107, 1280, 1024, 8, MD_XGI315 }, + { 0x4D, 0x011a, 0x011a, 1280, 1024, 16, MD_XGI315 }, + { 0x65, 0x013d, 0x011b, 1280, 1024, 32, MD_XGI315 }, + { 0x26, 0x0000, 0x0000, 1400, 1050, 8, MD_XGI315 }, + { 0x27, 0x0000, 0x0000, 1400, 1050, 16, MD_XGI315 }, + { 0x28, 0x0000, 0x0000, 1400, 1050, 32, MD_XGI315 }, + { 0x3C, 0x0130, 0x011c, 1600, 1200, 8, MD_XGI315 }, + { 0x3D, 0x0131, 0x011e, 1600, 1200, 16, MD_XGI315 }, + { 0x66, 0x013e, 0x011f, 1600, 1200, 32, MD_XGI315 }, + { 0x68, 0x013f, 0x0000, 1920, 1440, 8, MD_XGI315 }, + { 0x69, 0x0140, 0x0000, 1920, 1440, 16, MD_XGI315 }, + { 0x6B, 0x0141, 0x0000, 1920, 1440, 32, MD_XGI315 }, + { 0x6c, 0x0000, 0x0000, 2048, 1536, 8, MD_XGI315 }, + { 0x6d, 0x0000, 0x0000, 2048, 1536, 16, MD_XGI315 }, + { 0x6e, 0x0000, 0x0000, 2048, 1536, 32, MD_XGI315 }, + { 0 }, }; -/* TW: CR36 evaluation */ -static const unsigned short XGI300paneltype[] = { - LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, - LCD_1280x960, LCD_640x480, LCD_1024x600, LCD_1152x768, - LCD_1024x768, LCD_1024x768, LCD_1024x768, - LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768}; - static const unsigned short XGI310paneltype[] = { LCD_UNKNOWN, LCD_800x600, LCD_1024x768, LCD_1280x1024, LCD_640x480, LCD_1024x600, LCD_1152x864, LCD_1280x960, diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 21c0378..85dbf32 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -156,25 +156,14 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, unsigned short ModeNo = modeno; unsigned short ModeIdIndex = 0, ClockIndex = 0; unsigned short RefreshRateTableIndex = 0; - - /* unsigned long temp = 0; */ int Clock; InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); + XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr); + RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - /* - temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ; - if (!temp) { - printk(KERN_ERR "Could not find mode %x\n", ModeNo); - return 65000; - } - - RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex; - RefreshRateTableIndex += (rateindex - 1); - - */ ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000; @@ -190,7 +179,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, u32 *vmode) { unsigned short ModeNo = modeno; - unsigned short ModeIdIndex = 0, index = 0; + unsigned short ModeIdIndex, index = 0; unsigned short RefreshRateTableIndex = 0; unsigned short VRE, VBE, VRS, VBS, VDE, VT; @@ -199,16 +188,10 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, unsigned long cr_data3; int A, B, C, D, E, F, temp, j; InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr); + if (!XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr)) + return 0; RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - /* - temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr); - if (!temp) - return 0; - - RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex; - RefreshRateTableIndex += (rateindex - 1); - */ index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5]; @@ -219,12 +202,6 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8); A = HT + 5; - /* - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1]; - - Horizontal display enable end - HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6); - */ HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1; E = HDE + 1; @@ -358,7 +335,6 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr) { - XGI_Pr->RelIO = BaseAddr; XGI_Pr->P3c4 = BaseAddr + 0x14; XGI_Pr->P3d4 = BaseAddr + 0x24; XGI_Pr->P3c0 = BaseAddr + 0x10; @@ -414,19 +390,26 @@ static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info) static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info, const char *name) { - int i = 0, j = 0, l; + unsigned int xres; + unsigned int yres; + unsigned int bpp; + int i; - while (XGIbios_mode[i].mode_no != 0) { - l = min(strlen(name), strlen(XGIbios_mode[i].name)); - if (!strncmp(name, XGIbios_mode[i].name, l)) { + if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3) + goto invalid_mode; + + if (bpp == 24) + bpp = 32; /* That's for people who mix up color and fb depth. */ + + for (i = 0; XGIbios_mode[i].mode_no != 0; i++) + if (XGIbios_mode[i].xres == xres && + XGIbios_mode[i].yres == yres && + XGIbios_mode[i].bpp == bpp) { xgifb_info->mode_idx = i; - j = 1; - break; + return; } - i++; - } - if (!j) - pr_info("Invalid mode '%s'\n", name); +invalid_mode: + pr_info("Invalid mode '%s'\n", name); } static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info, @@ -1088,7 +1071,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; #if defined(__powerpc__) - u8 sr_data, cr_data; + u8 cr_data; #endif unsigned int drate = 0, hrate = 0; int found_mode = 0; @@ -1162,8 +1145,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = - XGIbios_mode[xgifb_info->mode_idx].rate_idx; + xgifb_info->rate_idx = 1; xgifb_info->refresh_rate = 60; } @@ -1680,17 +1662,6 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) ChannelNum = 1; break; - case XG45: - if (tmp == 1) - ChannelNum = 2; - else if (tmp == 2) - ChannelNum = 3; - else if (tmp == 3) - ChannelNum = 4; - else - ChannelNum = 1; - break; - case XG40: default: if (tmp == 2) @@ -1911,11 +1882,9 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_base = pci_resource_start(pdev, 1); xgifb_info->mmio_size = pci_resource_len(pdev, 1); xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30; - hw_info->pjIOAddress = (unsigned char *)xgifb_info->vga_base; - /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */ - pr_info("Relocate IO address: %lx [%08lx]\n", - (unsigned long)pci_resource_start(pdev, 2), - xgifb_info->dev_info.RelIO); + pr_info("Relocate IO address: %Lx [%08lx]\n", + (u64) pci_resource_start(pdev, 2), + xgifb_info->vga_base); if (pci_enable_device(pdev)) { ret = -EIO; @@ -1927,7 +1896,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->display2_force = true; } - XGIRegInit(&xgifb_info->dev_info, (unsigned long)hw_info->pjIOAddress); + XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base); xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); @@ -1950,9 +1919,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, case PCI_DEVICE_ID_XGI_40: xgifb_info->chip = XG40; break; - case PCI_DEVICE_ID_XGI_41: - xgifb_info->chip = XG41; - break; case PCI_DEVICE_ID_XGI_42: xgifb_info->chip = XG42; break; @@ -2006,13 +1972,13 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base, xgifb_info->mmio_size); - pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n", - xgifb_info->video_base, + pr_info("Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n", + (u64) xgifb_info->video_base, xgifb_info->video_vbase, xgifb_info->video_size / 1024); - pr_info("MMIO at 0x%lx, mapped to 0x%p, size %ldk\n", - xgifb_info->mmio_base, xgifb_info->mmio_vbase, + pr_info("MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n", + (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase, xgifb_info->mmio_size / 1024); pci_set_drvdata(pdev, xgifb_info); @@ -2174,8 +2140,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgifb_info->refresh_rate = 60; if (XGIfb_search_refresh_rate(xgifb_info, xgifb_info->refresh_rate) == 0) { - xgifb_info->rate_idx = - XGIbios_mode[xgifb_info->mode_idx].rate_idx; + xgifb_info->rate_idx = 1; xgifb_info->refresh_rate = 60; } diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 37bb730..9068c5a 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -23,9 +23,7 @@ enum xgifb_display_type { enum XGI_CHIP_TYPE { XG40 = 32, - XG41, XG42, - XG45, XG20 = 48, XG21, XG27, @@ -66,9 +64,9 @@ struct xgifb_video_info { int chip_id; unsigned int video_size; - unsigned long video_base; + phys_addr_t video_base; void __iomem *video_vbase; - unsigned long mmio_base; + phys_addr_t mmio_base; unsigned long mmio_size; void __iomem *mmio_vbase; unsigned long vga_base; diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 3650bbf..c222d61 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -353,7 +353,6 @@ static void XGINew_DDR1x_DefaultRegister( XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo); switch (HwDeviceExtension->jChipType) { - case XG41: case XG42: /* CR82 */ xgifb_reg_set(P3d4, @@ -556,8 +555,7 @@ static void XGINew_SetDRAMDefaultRegister340( xgifb_reg_set(P3d4, (0x8A + j), pVBInfo->CR40[1 + j][pVBInfo->ram_type]); - if ((HwDeviceExtension->jChipType == XG41) || - (HwDeviceExtension->jChipType == XG42)) + if (HwDeviceExtension->jChipType == XG42) xgifb_reg_set(P3d4, 0x8C, 0x87); xgifb_reg_set(P3d4, @@ -854,78 +852,6 @@ static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension, pVBInfo->ram_channel = 1; /* Single channel */ xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/ break; - case XG41: - if (XGINew_CheckFrequence(pVBInfo) == 1) { - pVBInfo->ram_bus = 32; /* 32 bits */ - pVBInfo->ram_channel = 3; /* Quad Channel */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4C); - - if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x48); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x49); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 3; - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x3C); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x38); - - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; - else - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x39); - } else { /* DDR */ - pVBInfo->ram_bus = 64; /* 64 bits */ - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xA1); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x5A); - - if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x53); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 2; /* Dual channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x21); - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x4A); - - if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) - return; - - pVBInfo->ram_channel = 1; /* Single channels */ - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42); - - if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1) - return; - else - xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x43); - } - - break; - case XG42: /* XG42 SR14 D[3] Reserve @@ -1478,7 +1404,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + pVBInfo->BaseAddr = xgifb_info->vga_base; /* Newdebugcode(0x99); */ diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 60d4adf..b2f4338 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -16,36 +16,6 @@ #define IndexMask 0xff -static const unsigned short XGINew_MDA_DAC[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F}; - -static const unsigned short XGINew_CGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F}; - -static const unsigned short XGINew_EGA_DAC[] = { - 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15, - 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35, - 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D, - 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D, - 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17, - 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37, - 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F, - 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F}; - static const unsigned short XGINew_VGA_DAC[] = { 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, @@ -60,8 +30,7 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable; - pVBInfo->StandTable = (struct SiS_StandTable_S *) XGI330_StandTable; + pVBInfo->StandTable = (struct SiS_StandTable_S *) &XGI330_StandTable; pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable; pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table @@ -182,38 +151,17 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) } -static unsigned char XGI_GetModePtr(unsigned short ModeNo, - unsigned short ModeIdIndex, - struct vb_device_info *pVBInfo) -{ - unsigned char index; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_StTableIndex; - else { - if (pVBInfo->ModeType <= 0x02) - index = 0x1B; /* 02 -> ModeEGA */ - else - index = 0x0F; - } - return index; /* Get pVBInfo->StandTable index */ -} - static void XGI_SetSeqRegs(unsigned short ModeNo, - unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char tempah, SRdata; unsigned short i, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - tempah = pVBInfo->StandTable[StandTableIndex].SR[0]; + tempah = pVBInfo->StandTable->SR[0]; i = XGI_SetCRT2ToLCDA; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -230,13 +178,12 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, for (i = 02; i <= 04; i++) { /* Get SR2,3,4 from file */ - SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; + SRdata = pVBInfo->StandTable->SR[i - 1]; xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ } } static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, - unsigned short StandTableIndex, struct vb_device_info *pVBInfo) { unsigned char CRTCdata; @@ -248,26 +195,22 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, for (i = 0; i <= 0x18; i++) { /* Get CRTC from file */ - CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; + CRTCdata = pVBInfo->StandTable->CRTC[i]; xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ } } static void XGI_SetATTRegs(unsigned short ModeNo, - unsigned short StandTableIndex, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char ARdata; unsigned short i, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; for (i = 0; i <= 0x13; i++) { - ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i]; + ARdata = pVBInfo->StandTable->ATTR[i]; if (modeflag & Charx8Dot) { /* ifndef Dot9 */ if (i == 0x13) { if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -295,15 +238,14 @@ static void XGI_SetATTRegs(unsigned short ModeNo, outb(0x20, pVBInfo->P3c0); } -static void XGI_SetGRCRegs(unsigned short StandTableIndex, - struct vb_device_info *pVBInfo) +static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) { unsigned char GRdata; unsigned short i; for (i = 0; i <= 0x08; i++) { /* Get GR from file */ - GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; + GRdata = pVBInfo->StandTable->GRC[i]; xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ } @@ -344,12 +286,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, { unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - if (ModeNo <= 0x13) - /* si+St_ModeFlag */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; tempax = 0; @@ -584,11 +521,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, data &= 0x80; data = data >> 2; - if (ModeNo <= 0x13) - i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; i &= DoubleScanMode; if (i) data |= 0x80; @@ -641,158 +574,97 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned char StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; + unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; unsigned short Temp1, Temp2, Temp3; - if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - /* CR04 HRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; - /* SR2E [7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - /* Tempbx: CR05 HRE */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - /* SR2F [7:2]->HRE */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* Tempax: CR16 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; - Tempbx = Tempax; /* Tempbx=Tempax */ - Tempax &= 0x01; /* Tempax: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */ - - /* Tempax: CR7 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */ - Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */ - Tempcx <<= 5; /* Tempcx[7]: VRS[8] */ - Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */ - /* SR34[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx); - - /* Temp1[8]: VRS[8] unsigned char -> unsigned short */ - Temp1 = Tempcx << 1; - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; /* Tempax[7]: CR7[7] */ - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - - /* CR16 VRE */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */ - Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */ - Temp3 = Temp1 & 0x0F; /* Temp3[3:0]: VRS[3:0] */ - if (Tempax < Temp3) /* VRE[3:0]<VRS[3:0] */ - Temp2 |= 0x10; /* Temp2: VRE + 0x10 */ - Temp2 &= 0xFF; /* Temp2[7:0]: VRE[7:0] */ - Tempax = (unsigned char) Temp2; /* Tempax[7:0]: VRE[7:0] */ - Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* [10:9]->[1:0] */ - Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */ - Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempcx = Tempax; /* Tempcx: HRS */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ - Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ - Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ - Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ - Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ - Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ - Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ - - Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ - Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ - - Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ - if (Tempax < Tempcx) /* HRE < HRS */ - Temp2 |= 0x40; /* Temp2 + 0x40 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ - Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ - Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ - Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ - /* SR2F D[7:2]->HRE, D[1:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; - Tempbx = Tempax; /* Tempbx: VRS */ - Tempax &= 0x01; /* Tempax[0]: VRS[0] */ - xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ - /* CR7[2][7] VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; - Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ - Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ - Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ - Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ - - Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ - Temp1 <<= 1; /* Temp1[8]: VRS[8] */ - Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ - Tempax &= 0x80; - Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ - Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ - /* Tempax: SRA */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* Tempax[3]: VRS[3] */ - Temp2 = Tempax; - Temp2 <<= 7; /* Temp2[10]: VRS[10] */ - Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SRA */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ - Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ - - Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ - if (Tempax < Temp3) /* VRE < VRS */ - Temp2 |= 0x20; /* VRE + 0x20 */ - - Temp2 &= 0xFF; - Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ - Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ - Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ - Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ - Tempbx = (unsigned char) Temp1; - Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ - Tempax &= 0x7F; - /* SR3F D[7:2]->VRE D[1:0]->VRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); - } + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempcx = Tempax; /* Tempcx: HRS */ + /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); + + Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ + Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ + Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ + Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ + Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ + Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ + Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ + + Temp2 = Temp1 & 0x3C0; /* Temp2[9:6]: HRS[9:6] */ + Temp2 |= Tempax; /* Temp2[9:0]: HRE[9:0] */ + + Tempcx &= 0x3F; /* Tempcx[5:0]: HRS[5:0] */ + if (Tempax < Tempcx) /* HRE < HRS */ + Temp2 |= 0x40; /* Temp2 + 0x40 */ + + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: HRE[7:0] */ + Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */ + Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */ + Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */ + /* SR2F D[7:2]->HRE, D[1:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); + + /* CR10 VRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + Tempbx = Tempax; /* Tempbx: VRS */ + Tempax &= 0x01; /* Tempax[0]: VRS[0] */ + xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ + /* CR7[2][7] VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ + Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ + Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ + Tempcx |= Tempdx; /* Tempcx[7:0]: VRS[8:1] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempcx); /* SR34[8:1]->VRS */ + + Temp1 = Tempdx; /* Temp1[7]: Tempdx[7] */ + Temp1 <<= 1; /* Temp1[8]: VRS[8] */ + Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */ + Tempax &= 0x80; + Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ + Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ + /* Tempax: SRA */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax &= 0x08; /* Tempax[3]: VRS[3] */ + Temp2 = Tempax; + Temp2 <<= 7; /* Temp2[10]: VRS[10] */ + Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ + + /* Tempax: CR11 VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + /* Tempbx: SRA */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Temp2 = Temp1 & 0x7E0; /* Temp2[10:5]: VRS[10:5] */ + Temp2 |= Tempax; /* Temp2[10:5]: VRE[10:5] */ + + Temp3 = Temp1 & 0x1F; /* Temp3[4:0]: VRS[4:0] */ + if (Tempax < Temp3) /* VRE < VRS */ + Temp2 |= 0x20; /* VRE + 0x20 */ + + Temp2 &= 0xFF; + Tempax = (unsigned char) Temp2; /* Tempax: VRE[7:0] */ + Tempax <<= 2; /* Tempax[7:0]; VRE[5:0]00 */ + Temp1 &= 0x600; /* Temp1[10:9]: VRS[10:9] */ + Temp1 >>= 9; /* Temp1[1:0]: VRS[10:9] */ + Tempbx = (unsigned char) Temp1; + Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */ + Tempax &= 0x7F; + /* SR3F D[7:2]->VRE D[1:0]->VRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); } static void XGI_SetXG27CRTC(unsigned short ModeNo, @@ -800,139 +672,88 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx; - - if (ModeNo <= 0x13) { - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - /* CR04 HRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; - /* SR2E [7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - /* Tempbx: CR05 HRE */ - Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; - Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */ - Tempcx = Tempax; - Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */ - Tempdx = Tempcx | Tempbx; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */ - if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */ - Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */ - Tempdx <<= 2; /* Tempdx << 2 */ - /* SR2F [7:2]->HRE */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* Tempax: CR10 VRS */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */ - Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */ - /* Tempax[7][2]: CR7[7][2] VRS[9][8] */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - Tempbx = Tempax; /* Tempbx=CR07 */ - Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */ - Tempax >>= 2; - /* SR35 D[0]->VRS D[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */ - Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */ - - /* CR11 VRE */ - Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; - Tempax &= 0x0F; /* Tempax: VRE[3:0] */ - Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */ - Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */ - Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */ - if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */ - Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */ - /* Tempax[7:0]: VRE[7:0] */ - Tempax = (unsigned char) Tempbx & 0xFF; - Tempax <<= 2; /* Tempax << 2: VRE[5:0] */ - Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */ - /* SR3F D[7:2]->VRE D[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - /* SR35 D[2:1]->VRS[10:9] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); - } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempbx = Tempax; /* Tempbx: HRS[7:0] */ - /* SR2E[7:0]->HRS */ - xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - - /* SR0B */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ - Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ - Tempax &= 0x04; /* Tempax[2]: HRE[5] */ - Tempax <<= 3; /* Tempax[5]: HRE[5] */ - Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ - - Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ - Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ - - /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; - Tempax &= 0x3F; /* Tempax: HRS[5:0] */ - if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ - Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ - Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ - Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ - Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ - /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ - xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); - xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); - - /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; - /* SR34[7:0]->VRS[7:0] */ - xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); - - Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ - /* CR7[7][2] VRS[9][8] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; - Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ - Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ - Tempax >>= 2; /* Tempax[0]: VRS[8] */ - /* SR35[0]: VRS[8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); - Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ - Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ - /* Tempax: SR0A */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempax &= 0x08; /* SR0A[3] VRS[10] */ - Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ - - /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; - Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ - /* Tempbx: SR0A */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; - Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ - Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ - Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ - Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ - Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ - Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ - - if (Tempbx <= Tempcx) /* VRE <= VRS */ - Tempbx |= 0x20; /* VRE + 0x20 */ - - /* Tempax: Tempax[7:0]; VRE[5:0]00 */ - Tempax = (Tempbx << 2) & 0xFF; - /* SR3F[7:2]:VRE[5:0] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); - Tempax = Tempcx >> 8; - /* SR35[2:0]:VRS[10:8] */ - xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); - } + unsigned short index, Tempax, Tempbx, Tempcx; + + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempbx = Tempax; /* Tempbx: HRS[7:0] */ + /* SR2E[7:0]->HRS */ + xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); + + /* SR0B */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ + Tempcx = Tempax; /* Tempcx: HRE[4:0] */ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempax &= 0x04; /* Tempax[2]: HRE[5] */ + Tempax <<= 3; /* Tempax[5]: HRE[5] */ + Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ + + Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */ + Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ + + /* Tempax: CR4 HRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempax &= 0x3F; /* Tempax: HRS[5:0] */ + if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ + Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ + + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ + Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ + Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ + Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ + /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */ + xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); + xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); + + /* CR10 VRS */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + /* SR34[7:0]->VRS[7:0] */ + xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); + + Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ + /* CR7[7][2] VRS[9][8] */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ + Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ + Tempax >>= 2; /* Tempax[0]: VRS[8] */ + /* SR35[0]: VRS[8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); + Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ + Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ + /* Tempax: SR0A */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax &= 0x08; /* SR0A[3] VRS[10] */ + Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ + + /* Tempax: CR11 VRE */ + Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ + /* Tempbx: SR0A */ + Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ + Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ + Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ + Tempbx = Tempcx; /* Tempbx: VRS[10:0] */ + Tempbx &= 0x7E0; /* Tempbx[10:5]: VRS[10:5] */ + Tempbx |= Tempax; /* Tempbx: VRS[10:5]VRE[4:0] */ + + if (Tempbx <= Tempcx) /* VRE <= VRS */ + Tempbx |= 0x20; /* VRE + 0x20 */ + + /* Tempax: Tempax[7:0]; VRE[5:0]00 */ + Tempax = (Tempbx << 2) & 0xFF; + /* SR3F[7:2]:VRE[5:0] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); + Tempax = Tempcx >> 8; + /* SR35[2:0]:VRS[10:8] */ + xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); } static void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo) @@ -954,7 +775,7 @@ static void xgifb_set_lcd(int chip_id, unsigned short RefreshRateTableIndex, unsigned short ModeNo) { - unsigned short Data, Temp, b3CC; + unsigned short Data, Temp; unsigned short XGI_P3cc; XGI_P3cc = pVBInfo->P3cc; @@ -995,23 +816,13 @@ static void xgifb_set_lcd(int chip_id, xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - if (ModeNo <= 0x13) { - b3CC = (unsigned char) inb(XGI_P3cc); - if (b3CC & 0x40) - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - if (b3CC & 0x80) - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } else { - Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (Data & 0x4000) - /* Hsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - if (Data & 0x8000) - /* Vsync polarity */ - xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); - } + Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + if (Data & 0x4000) + /* Hsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); + if (Data & 0x8000) + /* Vsync polarity */ + xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); } /* --------------------------------------------------------------------- */ @@ -1024,30 +835,22 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo, unsigned short RefreshRateTableIndex) { - int i, index = -1; + int index = -1; xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ - if (ModeNo <= 0x13) { - for (i = 0; i < 12; i++) { - if (ModeNo == pVBInfo->UpdateCRT1[i].ModeID) - index = i; - } - } else { - if (ModeNo == 0x2E && - (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == - RES640x480x60)) - index = 12; - else if (ModeNo == 0x2E && - (pVBInfo->RefIndex[RefreshRateTableIndex]. + if (ModeNo == 0x2E && + (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == + RES640x480x60)) + index = 12; + else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRT1CRTC == RES640x480x72)) - index = 13; - else if (ModeNo == 0x2F) - index = 14; - else if (ModeNo == 0x50) - index = 15; - else if (ModeNo == 0x59) - index = 16; - } + index = 13; + else if (ModeNo == 0x2F) + index = 14; + else if (ModeNo == 0x50) + index = 15; + else if (ModeNo == 0x59) + index = 16; if (index != -1) { xgifb_reg_set(pVBInfo->P3d4, 0x02, @@ -1061,20 +864,6 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, } } -static unsigned short XGI_GetResInfo(unsigned short ModeNo, - unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) -{ - unsigned short resindex; - - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - return resindex; -} - static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, @@ -1084,33 +873,25 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned char data; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempax = pVBInfo->StResInfo[resindex].HTotal; - tempbx = pVBInfo->StResInfo[resindex].VTotal; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = pVBInfo->ModeResInfo[resindex].HTotal; - tempbx = pVBInfo->ModeResInfo[resindex].VTotal; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempax = pVBInfo->ModeResInfo[resindex].HTotal; + tempbx = pVBInfo->ModeResInfo[resindex].VTotal; if (modeflag & HalfDCLK) tempax = tempax >> 1; - if (ModeNo > 0x13) { - if (modeflag & HalfDCLK) - tempax = tempax << 1; + if (modeflag & HalfDCLK) + tempax = tempax << 1; - temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (temp & InterlaceMode) - tempbx = tempbx >> 1; + if (temp & InterlaceMode) + tempbx = tempbx >> 1; - if (modeflag & DoubleScanMode) - tempbx = tempbx << 1; - } + if (modeflag & DoubleScanMode) + tempbx = tempbx << 1; tempcx = 8; @@ -1258,18 +1039,10 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, unsigned short CRT2Index, VCLKIndex; unsigned short modeflag, resinfo; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ @@ -1318,23 +1091,13 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex += 25; } } else { /* for CRT2 */ - /* Port 3cch */ - VCLKIndex = (unsigned char) inb((pVBInfo->P3ca + 0x02)); - VCLKIndex = ((VCLKIndex >> 2) & 0x03); - if (ModeNo > 0x13) { - /* di+Ext_CRTVCLK */ - VCLKIndex = pVBInfo->RefIndex[ - RefreshRateTableIndex]. + /* di+Ext_CRTVCLK */ + VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRTVCLK; - VCLKIndex &= IndexMask; - } + VCLKIndex &= IndexMask; } } else { /* LVDS */ - if (ModeNo <= 0x13) - VCLKIndex = CRT2Index; - else - VCLKIndex = CRT2Index; - + VCLKIndex = CRT2Index; VCLKIndex = VCLKIndex >> 6; if ((pVBInfo->LCDResInfo == Panel_800x600) || (pVBInfo->LCDResInfo == Panel_320x480)) @@ -1431,27 +1194,13 @@ static void XGI_SetCRT1FIFO(unsigned short ModeNo, data &= 0xfe; xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */ - if (ModeNo > 0x13) { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); - data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); - data |= 0x01; - xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); - } else { - if (HwDeviceExtension->jChipType == XG27) { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x0E); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xC0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x20); - } else { - xgifb_reg_set(pVBInfo->P3c4, 0x08, 0xAE); - data = xgifb_reg_get(pVBInfo->P3c4, 0x09); - data &= 0xF0; - xgifb_reg_set(pVBInfo->P3c4, 0x09, data); - } - } + xgifb_reg_set(pVBInfo->P3c4, 0x08, 0x34); + data = xgifb_reg_get(pVBInfo->P3c4, 0x09); + data &= 0xC0; + xgifb_reg_set(pVBInfo->P3c4, 0x09, data | 0x30); + data = xgifb_reg_get(pVBInfo->P3c4, 0x3D); + data |= 0x01; + xgifb_reg_set(pVBInfo->P3c4, 0x3D, data); if (HwDeviceExtension->jChipType == XG21) XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */ @@ -1466,13 +1215,9 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned char index; - if (ModeNo <= 0x13) - VCLK = 0; - else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - index &= IndexMask; - VCLK = pVBInfo->VCLKData[index].CLOCK; - } + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index &= IndexMask; + VCLK = pVBInfo->VCLKData[index].CLOCK; data = xgifb_reg_get(pVBInfo->P3c4, 0x32); data &= 0xf3; @@ -1508,44 +1253,26 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, xres; - if (ModeNo > 0x13) { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_InfoFlag; - } else - /* si+St_ModeFlag */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); - if (ModeNo > 0x13) - data = infoflag; - else - data = 0; - + data = infoflag; data2 = 0; - - if (ModeNo > 0x13) { - if (pVBInfo->ModeType > 0x02) { - data2 |= 0x02; - data3 = pVBInfo->ModeType - ModeVGA; - data3 = data3 << 2; - data2 |= data3; - } - } - + data2 |= 0x02; + data3 = pVBInfo->ModeType - ModeVGA; + data3 = data3 << 2; + data2 |= data3; data &= InterlaceMode; if (data) data2 |= 0x20; xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) - xres = pVBInfo->StResInfo[resindex].HTotal; - else - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ data = 0x0000; if (infoflag & InterlaceMode) { @@ -1568,18 +1295,10 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, if (modeflag & LineCompareOff) data2 |= 0x08; - if (ModeNo > 0x13) { - if (pVBInfo->ModeType == ModeEGA) - data2 |= 0x40; - } - xgifb_reg_and_or(pVBInfo->P3c4, 0x0F, ~0x48, data2); data = 0x60; - if (pVBInfo->ModeType != ModeText) { - data = data ^ 0x60; - if (pVBInfo->ModeType != ModeEGA) - data = data ^ 0xA0; - } + data = data ^ 0x60; + data = data ^ 0xA0; xgifb_reg_and_or(pVBInfo->P3c4, 0x21, 0x1F, data); XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex, @@ -1644,38 +1363,13 @@ static void XGI_WriteDAC(unsigned short dl, static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, - ah, dh; - const unsigned short *table = NULL; - - if (ModeNo <= 0x13) - data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - data &= DACInfoFlag; - time = 64; - - if (data == 0x00) - table = XGINew_MDA_DAC; - else if (data == 0x08) - table = XGINew_CGA_DAC; - else if (data == 0x10) - table = XGINew_EGA_DAC; - else if (data == 0x18) { - time = 256; - table = XGINew_VGA_DAC; - } - - if (time == 256) - j = 16; - else - j = time; + unsigned short data, data2, i, k, m, n, o, si, di, bx, dl, al, ah, dh; + const unsigned short *table = XGINew_VGA_DAC; outb(0xFF, pVBInfo->P3c6); outb(0x00, pVBInfo->P3c8); - for (i = 0; i < j; i++) { + for (i = 0; i < 16; i++) { data = table[i]; for (k = 0; k < 3; k++) { @@ -1692,45 +1386,43 @@ static void XGI_LoadDAC(unsigned short ModeNo, unsigned short ModeIdIndex, } } - if (time == 256) { - for (i = 16; i < 32; i++) { - data = table[i]; - - for (k = 0; k < 3; k++) - outb(data, pVBInfo->P3c9); - } + for (i = 16; i < 32; i++) { + data = table[i]; - si = 32; + for (k = 0; k < 3; k++) + outb(data, pVBInfo->P3c9); + } - for (m = 0; m < 9; m++) { - di = si; - bx = si + 0x04; - dl = 0; + si = 32; - for (n = 0; n < 3; n++) { - for (o = 0; o < 5; o++) { - dh = table[si]; - ah = table[di]; - al = table[bx]; - si++; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } + for (m = 0; m < 9; m++) { + di = si; + bx = si + 0x04; + dl = 0; - si -= 2; + for (n = 0; n < 3; n++) { + for (o = 0; o < 5; o++) { + dh = table[si]; + ah = table[di]; + al = table[bx]; + si++; + XGI_WriteDAC(dl, ah, al, dh, pVBInfo); + } - for (o = 0; o < 3; o++) { - dh = table[bx]; - ah = table[di]; - al = table[si]; - si--; - XGI_WriteDAC(dl, ah, al, dh, pVBInfo); - } + si -= 2; - dl++; + for (o = 0; o < 3; o++) { + dh = table[bx]; + ah = table[di]; + al = table[si]; + si--; + XGI_WriteDAC(dl, ah, al, dh, pVBInfo); } - si += 5; + dl++; } + + si += 5; } } @@ -1740,34 +1432,20 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, { unsigned short resindex, xres, yres, modeflag; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - else - /* si+Ext_ResInfo */ - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + /* si+Ext_ResInfo */ + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; - yres = pVBInfo->ModeResInfo[resindex].VTotal; - } - if (ModeNo > 0x13) { - if (modeflag & HalfDCLK) - xres = xres << 1; + xres = pVBInfo->ModeResInfo[resindex].HTotal; + yres = pVBInfo->ModeResInfo[resindex].VTotal; - if (modeflag & DoubleScanMode) - yres = yres << 1; - } + if (modeflag & HalfDCLK) + xres = xres << 1; + + if (modeflag & DoubleScanMode) + yres = yres << 1; if (xres == 720) xres = 640; @@ -1789,32 +1467,16 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempbx = BX; - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x0f; if (tempbx <= 1) { /* ExpLink */ - if (ModeNo <= 0x13) { - /* find no Ext_CRT2CRTC2 */ - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - tempal = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - if (ModeNo <= 0x13) - tempal = pVBInfo->SModeIDTable[ModeIdIndex]. - St_CRT2CRTC2; - else - tempal = pVBInfo->RefIndex[ - RefreshRateTableIndex]. + tempal = pVBInfo->RefIndex[RefreshRateTableIndex]. Ext_CRT2CRTC2; } @@ -1882,9 +1544,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempbx = tempdi[i].MASK; tempdx = pVBInfo->LCDInfo; - if (ModeNo <= 0x13) /* alan 09/10/2003 */ - tempdx |= SetLCDStdMode; - if (modeflag & HalfDCLK) tempdx |= SetLCDLowResolution; @@ -2238,15 +1897,8 @@ static void *XGI_GetTVPtr(unsigned short BX, unsigned short ModeNo, struct XGI330_TVDataTablStruct *tempdi = NULL; tempbx = BX; - - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - } - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; table = tempbx; @@ -2413,11 +2065,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - else - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - + index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; index = index & IndexMask; tempbx = 0; @@ -2530,14 +2178,10 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; unsigned long temp, temp1, temp2, temp3, push3; - struct XGI330_LCDDataDesStruct *LCDPtr = NULL; + struct XGI_LCDDesStruct *LCDPtr = NULL; struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; - if (ModeNo > 0x13) - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - else - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempbx = 3; if (pVBInfo->LCDInfo & EnableScalingLCD) LCDPtr1 = @@ -2550,7 +2194,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, pVBInfo); else LCDPtr = - (struct XGI330_LCDDataDesStruct *) + (struct XGI_LCDDesStruct *) XGI_GetLcdPtr( tempbx, ModeNo, @@ -2829,12 +2473,8 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, unsigned short index, modeflag; unsigned char tempal; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */ @@ -2895,9 +2535,6 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */ - if (ModeNo <= 0x13) - return tempal; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; return tempal; } @@ -3079,11 +2716,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempax, push, tempbx, temp, modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; pVBInfo->SetFlag = 0; pVBInfo->ModeType = modeflag & ModeTypeMask; tempbx = 0; @@ -3283,17 +2916,8 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, resinfo = 0; if (pVBInfo->VBInfo & SetCRT2ToTV) { - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ModeFlag; /* si+St_ModeFlag */ - resinfo = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ResInfo; /* si+St_ResInfo */ - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex]. - Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex]. - Ext_RESINFO; /* si+Ext_ResInfo */ - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; if (pVBInfo->VBInfo & SetCRT2ToTV) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); @@ -3380,15 +3004,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, pVBInfo->LCDTypeInfo = 0; pVBInfo->LCDInfo = 0; - if (ModeNo <= 0x13) { - /* si+St_ModeFlag // */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - /* si+Ext_ResInfo // */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo // */ + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ tempbx = temp & 0x0F; @@ -3442,8 +3060,8 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo - & SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo - == 9) && (!(tempbx & EnableScalingLCD))) + & SetCRT2ToLCD) && (resinfo == 9) && + (!(tempbx & EnableScalingLCD))) /* set to center in 1280x1024 LCDB for Panel_1400x1050 */ tempbx |= SetLCDtoNonExpanding; } @@ -3453,12 +3071,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, if (!(tempbx & SetLCDtoNonExpanding)) { tempbx |= XGI_EnableLVDSDDA; } else { - if (ModeNo > 0x13) { - if (pVBInfo->LCDResInfo - == Panel_1024x768) { - if (resinfo == 4) {/* 512x384 */ - tempbx |= XGI_EnableLVDSDDA; - } + if (pVBInfo->LCDResInfo == Panel_1024x768) { + if (resinfo == 4) {/* 512x384 */ + tempbx |= XGI_EnableLVDSDDA; } } } @@ -3474,56 +3089,17 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, pVBInfo->LCDInfo = tempbx; - if (pVBInfo->IF_DEF_LVDS == 0) { - if (tempax & (LockLCDBToA | StLCDBToA)) { - if (pVBInfo->VBInfo & SetInSlaveMode) { - if (!(tempax & LockLCDBToA)) { - if (ModeNo <= 0x13) { - pVBInfo->VBInfo &= - ~(SetSimuScanMode | - SetInSlaveMode | - SetCRT2ToLCD); - pVBInfo->VBInfo |= - XGI_SetCRT2ToLCDA | - SetCRT2ToDualEdge; - } - } - } - } - } - return 1; } unsigned char XGI_SearchModeID(unsigned short ModeNo, unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo) { - if (ModeNo <= 5) - ModeNo |= 1; - if (ModeNo <= 0x13) { - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == - ModeNo) - break; - if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == - 0xFF) - return 0; - } - - if (ModeNo == 0x07) - (*ModeIdIndex)++; /* 400 lines */ - if (ModeNo <= 3) - (*ModeIdIndex) += 2; /* 400 lines */ - /* else 350 lines */ - } else { - for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == - ModeNo) - break; - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == - 0xFF) - return 0; - } + for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) + break; + if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) + return 0; } return 1; @@ -3789,22 +3365,17 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, { unsigned short xres, yres, modeflag, resindex; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - if (modeflag & HalfDCLK) - xres *= 2; + if (modeflag & HalfDCLK) + xres *= 2; - if (modeflag & DoubleScanMode) - yres *= 2; - } + if (modeflag & DoubleScanMode) + yres *= 2; if (pVBInfo->VBInfo & SetCRT2ToLCD) { if (pVBInfo->IF_DEF_LVDS == 0) { @@ -3868,37 +3439,23 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, struct vb_device_info *pVBInfo) { unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, - StandTableIndex, CRT1Index; + CRT1Index; pVBInfo->RVBHCMAX = 1; pVBInfo->RVBHCFACT = 1; - - if (ModeNo <= 0x13) { - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0]; - tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6]; - temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7]; - } else { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT1CRTC; - CRT1Index &= IndexMask; - temp1 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[0]; - temp2 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[5]; - tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[8]; - tempcx = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8; - tempcx &= 0x0100; - tempcx = tempcx << 2; - tempbx |= tempcx; - temp1 = (unsigned short) pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[9]; - } + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; + temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); + tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8]; + tempcx = (unsigned short) + pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8; + tempcx &= 0x0100; + tempcx = tempcx << 2; + tempbx |= tempcx; + temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; if (temp1 & 0x01) tempbx |= 0x0100; @@ -3928,16 +3485,9 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, struct SiS_LCDData *LCDPtr = NULL; struct SiS_TVData *TVPtr = NULL; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; pVBInfo->NewFlickerMode = 0; pVBInfo->RVBHRS = 50; @@ -4141,11 +3691,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo, short index; unsigned short modeflag; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = (modeflag & ModeTypeMask) - ModeEGA; if (index < 0) @@ -4164,11 +3710,7 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, ColorDepth[] = { 0x01, 0x02, 0x04 }; modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; - if (ModeNo <= 0x14) - infoflag = 0; - else - infoflag = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; index = (modeinfo >> 8) & 0xFF; @@ -4228,12 +3770,9 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0; - if (ModeNo > 0x13) { - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); @@ -4254,17 +3793,10 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0; - if (ModeNo > 0x13) { - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - } - - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* bainy change table name */ if (modeflag & HalfDCLK) { @@ -4422,18 +3954,11 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short push1, push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo-> - RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - CRT1Index &= IndexMask; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetInSlaveMode)) return; @@ -4500,8 +4025,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, temp -= 6; if (pVBInfo->TVInfo & TVSimuMode) { temp -= 4; - if (ModeNo > 0x13) - temp -= 10; + temp -= 10; } } } else { @@ -4523,14 +4047,6 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->LCDResInfo != Panel_1280x960 && pVBInfo->VGAHDE >= 800) { temp -= 7; - if (pVBInfo->ModeType == ModeEGA && - pVBInfo->VGAVDE == 1024) { - temp += 15; - if (pVBInfo->LCDResInfo != - Panel_1280x1024) - temp += 7; - } - if (pVBInfo->VGAHDE >= 1280 && pVBInfo->LCDResInfo != Panel_1280x960 && (pVBInfo->LCDInfo & LCDNonExpanding)) @@ -4546,48 +4062,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, if (pVBInfo->VBInfo & SetCRT2ToTV) { if (pVBInfo->TVInfo & TVSimuMode) { - if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo - == 0x11) || (ModeNo == 0x13) || (ModeNo - == 0x0F)) { - xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x5b); - xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0x03); - } - - if ((ModeNo == 0x00) || (ModeNo == 0x01)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2A); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x61); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x2A); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x41); - xgifb_reg_set(pVBInfo->Part1Port, - 0x0C, 0xF0); - } - } - - if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo - == 0x07)) { - if (pVBInfo->TVInfo & SetNTSCTV) { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x54); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x00); - } else { - xgifb_reg_set(pVBInfo->Part1Port, - 0x07, 0x55); - xgifb_reg_set(pVBInfo->Part1Port, - 0x08, 0x00); - xgifb_reg_set(pVBInfo->Part1Port, - 0x0C, 0xF0); - } - } - - if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo - == 0x0D) || (ModeNo == 0x50)) { + if (ModeNo == 0x50) { if (pVBInfo->TVInfo & SetNTSCTV) { xgifb_reg_set(pVBInfo->Part1Port, 0x07, 0x30); @@ -4796,18 +4271,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long longtemp, tempeax, tempebx, temp2, tempecx; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempax = 0; @@ -5245,18 +4712,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LCDDesStruct *LCDBDesPtr = NULL; - if (ModeNo <= 0x13) { - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; - } else { - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT1CRTC; - CRT1Index &= IndexMask; - } + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) return; @@ -5274,16 +4734,6 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp); temp = 0x01; - if (pVBInfo->LCDResInfo == Panel_1280x1024) { - if (pVBInfo->ModeType == ModeEGA) { - if (pVBInfo->VGAHDE >= 1024) { - temp = 0x02; - if (pVBInfo->LCDInfo & XGI_LCDVESATiming) - temp = 0x01; - } - } - } - xgifb_reg_set(pVBInfo->Part2Port, 0x0B, temp); tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */ push1 = tempbx; @@ -5542,12 +4992,8 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char *tempdi; unsigned short modeflag; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); if (pVBInfo->TVInfo & TVSetPAL) { @@ -5605,13 +5051,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long tempebx, tempeax, templong; - if (ModeNo <= 0x13) - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - + /* si+Ext_ResInfo */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; temp = pVBInfo->RVBHCFACT; xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); @@ -5818,32 +5259,22 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, { unsigned short xres, yres, colordepth, modeflag, resindex; - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) { xres /= 9; xres *= 8; } - if (ModeNo > 0x13) { - if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) - xres *= 2; - - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) - yres *= 2; + if ((ModeNo > 0x13) && (modeflag & HalfDCLK)) + xres *= 2; - } + if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) + yres *= 2; if (xres > xgifb_info->lvds_data.LVDSHDE) return 0; @@ -5851,16 +5282,11 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, if (yres > xgifb_info->lvds_data.LVDSVDE) return 0; - if (ModeNo > 0x13) { - if (xres != xgifb_info->lvds_data.LVDSHDE || - yres != xgifb_info->lvds_data.LVDSVDE) { - colordepth = XGI_GetColorDepth(ModeNo, - ModeIdIndex, - pVBInfo); - if (colordepth > 2) - return 0; - - } + if (xres != xgifb_info->lvds_data.LVDSHDE || + yres != xgifb_info->lvds_data.LVDSVDE) { + colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo); + if (colordepth > 2) + return 0; } return 1; } @@ -5895,18 +5321,11 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, else XGI_SetXG21FPBits(pVBInfo); - resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); - if (ModeNo <= 0x13) { - xres = pVBInfo->StResInfo[resindex].HTotal; - yres = pVBInfo->StResInfo[resindex].VTotal; - /* si+St_ResInfo */ - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - } else { - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ - /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - } + resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + /* si+St_ModeFlag */ + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) xres = xres * 8 / 9; @@ -5914,8 +5333,6 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, LVDSHT = xgifb_info->lvds_data.LVDSHT; LVDSHBS = xres + (xgifb_info->lvds_data.LVDSHDE - xres) / 2; - if ((ModeNo <= 0x13) && (modeflag & HalfDCLK)) - LVDSHBS -= xres / 4; if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT; @@ -5933,7 +5350,7 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, LVDSVT = xgifb_info->lvds_data.LVDSVT; LVDSVBS = yres + (xgifb_info->lvds_data.LVDSVDE - yres) / 2; - if ((ModeNo > 0x13) && (modeflag & DoubleScanMode)) + if (modeflag & DoubleScanMode) LVDSVBS += yres / 2; if (LVDSVBS > LVDSVT) @@ -6527,7 +5944,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; + unsigned short tempbx; unsigned char tempah; @@ -6536,13 +5953,6 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo, tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex; - - tempbx += index; tempah = TVAntiFlickList[tempbx]; tempah = tempah << 4; @@ -6553,19 +5963,12 @@ static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx, index; + unsigned short tempbx; unsigned char tempah; tempbx = XGI_GetTVPtrIndex(pVBInfo); tempbx &= 0xFE; - - if (ModeNo <= 0x13) - index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex; - else - index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex; - - tempbx += index; tempah = TVEdgeList[tempbx]; tempah = tempah << 5; @@ -6631,13 +6034,7 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, return; } - if (ModeNo <= 0x13) - tempal = pVBInfo->SModeIDTable[ModeIdIndex]. - VB_StTVYFilterIndex; - else - tempal = pVBInfo->EModeIDTable[ModeIdIndex]. - VB_ExtTVYFilterIndex; - + tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; if (tempcl == 0) index = tempal * 4; else @@ -6712,16 +6109,14 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) { tempah = 0x40; /* BTDRAM */ - if (ModeNo > 0x13) { - tempcl = pVBInfo->ModeType; - tempcl -= ModeVGA; - if (tempcl >= 0) { - /* BT Color */ - tempah = (0x008 >> tempcl); - if (tempah == 0) - tempah = 1; - tempah |= 0x040; - } + tempcl = pVBInfo->ModeType; + tempcl -= ModeVGA; + if (tempcl >= 0) { + /* BT Color */ + tempah = (0x008 >> tempcl); + if (tempah == 0) + tempah = 1; + tempah |= 0x040; } if (pVBInfo->VBInfo & SetInSlaveMode) tempah ^= 0x50; /* BTDAC */ @@ -6797,10 +6192,8 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo, if (pVBInfo->VBInfo & SetCRT2ToTV) { tempah |= 0x020; - if (ModeNo > 0x13) { - if (pVBInfo->VBInfo & DriverMode) - tempah = tempah ^ 0x20; - } + if (pVBInfo->VBInfo & DriverMode) + tempah = tempah ^ 0x20; } xgifb_reg_and_or(pVBInfo->Part4Port, 0x0D, ~0x0BF, tempah); @@ -6925,13 +6318,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short RefreshRateTableIndex, i, modeflag, index, temp; - if (ModeNo <= 0x13) - modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; - else - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - - if (ModeNo < 0x14) - return 0xFFFF; + modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = xgifb_reg_get(pVBInfo->P3d4, 0x33); index = index >> pVBInfo->SelectCRT2Rate; @@ -7297,16 +6684,13 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { - unsigned short StandTableIndex, RefreshRateTableIndex, b3CC, temp; + unsigned short RefreshRateTableIndex, temp; - unsigned short XGINew_P3cc = pVBInfo->P3cc; - - StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo); - XGI_SetSeqRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - outb(pVBInfo->StandTable[StandTableIndex].MISC, pVBInfo->P3c2); - XGI_SetCRTCRegs(HwDeviceExtension, StandTableIndex, pVBInfo); - XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo); - XGI_SetGRCRegs(StandTableIndex, pVBInfo); + XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo); + outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2); + XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo); + XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo); + XGI_SetGRCRegs(pVBInfo); XGI_ClearExt1Regs(pVBInfo); if (HwDeviceExtension->jChipType == XG27) { @@ -7340,22 +6724,6 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, RefreshRateTableIndex, pVBInfo); } - if ((HwDeviceExtension->jChipType >= XG20) && - (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */ - if ((ModeNo == 0x00) | (ModeNo == 0x01)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x4E); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE9); - b3CC = (unsigned char) inb(XGINew_P3cc); - outb((b3CC |= 0x0C), XGINew_P3cc); - } else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo - == 0x0D)) { - xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x1B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE3); - b3CC = (unsigned char) inb(XGINew_P3cc); - outb((b3CC |= 0x0C), XGINew_P3cc); - } - } - if (HwDeviceExtension->jChipType >= XG21) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x38); if (temp & 0xA0) { @@ -7394,7 +6762,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, unsigned short ModeIdIndex; struct vb_device_info VBINF; struct vb_device_info *pVBInfo = &VBINF; - pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress; + pVBInfo->BaseAddr = xgifb_info->vga_base; pVBInfo->IF_DEF_LVDS = 0; pVBInfo->IF_DEF_LCDA = 1; @@ -7509,13 +6877,8 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, pVBInfo)) return 0; - if (ModeNo <= 0x13) { - pVBInfo->ModeType = pVBInfo->SModeIDTable[ModeIdIndex]. - St_ModeFlag & ModeTypeMask; - } else { - pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. + pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. Ext_ModeFlag & ModeTypeMask; - } pVBInfo->SetFlag = 0; pVBInfo->VBInfo = DisableCRT2Display; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index a5bd56a..38f47ff 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -10,28 +10,11 @@ struct XGI_LVDSCRT1VDataStruct { unsigned char Reg[7]; }; -struct XGI_StStruct { - unsigned char St_ModeID; - unsigned short St_ModeFlag; - unsigned char St_StTableIndex; - unsigned char St_CRT2CRTC; - unsigned char St_CRT2CRTC2; - unsigned char St_ResInfo; - unsigned char VB_StTVFlickerIndex; - unsigned char VB_StTVEdgeIndex; - unsigned char VB_StTVYFilterIndex; -}; - struct XGI_ExtStruct { unsigned char Ext_ModeID; unsigned short Ext_ModeFlag; unsigned short Ext_ModeInfo; - unsigned short Ext_Point; - unsigned short Ext_VESAID; - unsigned char Ext_VESAMEMSize; unsigned char Ext_RESINFO; - unsigned char VB_ExtTVFlickerIndex; - unsigned char VB_ExtTVEdgeIndex; unsigned char VB_ExtTVYFilterIndex; unsigned char REFindex; }; @@ -68,14 +51,6 @@ struct XGI_LCDDataTablStruct { unsigned short DATAPTR; }; -struct XGI330_LCDDataDesStruct { - unsigned short LCDHDES; - unsigned short LCDHRS; - unsigned short LCDVDES; - unsigned short LCDVRS; -}; - - struct XGI330_LVDSDataStruct { unsigned short VGAHT; unsigned short VGAVT; @@ -236,7 +211,6 @@ struct vb_device_info { void __iomem *FBAddr; unsigned long BaseAddr; - unsigned long RelIO; unsigned char (*CR6B)[4]; unsigned char (*CR6E)[4]; @@ -314,7 +288,6 @@ struct vb_device_info { struct XGI_TimingHStruct *TimingH; struct XGI_TimingVStruct *TimingV; - struct XGI_StStruct *SModeIDTable; struct SiS_StandTable_S *StandTable; struct XGI_ExtStruct *EModeIDTable; struct XGI_Ext2Struct *RefIndex; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index e8d6f67..d22e599 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -135,609 +135,92 @@ static unsigned char XGI330_SR33; static unsigned char XG40_CRCF = 0x13; static unsigned char XG40_DRAMTypeDefinition = 0xFF ; -static struct XGI_StStruct XGI330_SModeIDTable[] = { - {0x01, 0x9208, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00}, - {0x01, 0x1210, 0x14, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}, - {0x01, 0x1010, 0x17, 0x02, 0x11, 0x00, 0x00, 0x01, 0x01}, - {0x03, 0x8208, 0x03, 0x00, 0x14, 0x00, 0x00, 0x01, 0x02}, - {0x03, 0x0210, 0x16, 0x01, 0x04, 0x01, 0x00, 0x01, 0x02}, - {0x03, 0x0010, 0x18, 0x02, 0x15, 0x00, 0x00, 0x01, 0x03}, - {0x05, 0x9209, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04}, - {0x06, 0x8209, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05}, - {0x07, 0x0000, 0x07, 0x03, 0x05, 0x03, 0x00, 0x01, 0x03}, - {0x07, 0x0000, 0x19, 0x02, 0x15, 0x02, 0x00, 0x01, 0x03}, - {0x0d, 0x920a, 0x0d, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04}, - {0x0e, 0x820a, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05}, - {0x0f, 0x0202, 0x11, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05}, - {0x10, 0x0212, 0x12, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05}, - {0x11, 0x0212, 0x1a, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05}, - {0x12, 0x0212, 0x1b, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05}, - {0x13, 0x021b, 0x1c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04}, - {0x12, 0x0010, 0x18, 0x02, 0x24, 0x02, 0x00, 0x00, 0x05},/* St_CRT2CRTC2 - not sure */ - {0x12, 0x0210, 0x18, 0x01, 0x24, 0x01, 0x00, 0x00, 0x05},/* St_CRT2CRTC2 - not sure */ - {0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - - static struct XGI_ExtStruct XGI330_EModeIDTable[] = { - {0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08, - 0x05, 0x00, 0x00, 0x05, 0x05}, - {0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08, - 0x0d, 0x00, 0x00, 0x06, 0x3d}, - {0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08, - 0x0e, 0x00, 0x00, 0x06, 0x3e}, - {0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x3c, 0x0e3b, 0x070a, 0x3af2, 0x0130, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, + {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, + {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e}, + {0x31, 0x0a1b, 0x030d, 0x0d, 0x06, 0x3d}, + {0x32, 0x0a1b, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x33, 0x0a1d, 0x0a0d, 0x0d, 0x06, 0x3d}, + {0x34, 0x2a1d, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x35, 0x0a1f, 0x0a0d, 0x0d, 0x06, 0x3d}, + {0x36, 0x2a1f, 0x0a0e, 0x0e, 0x06, 0x3e}, + {0x38, 0x0a1b, 0x0508, 0x08, 0x00, 0x16}, + {0x3a, 0x0e3b, 0x0609, 0x09, 0x00, 0x1e}, + {0x3c, 0x0e3b, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE [2003/10/07] */ - {0x3d, 0x0e7d, 0x070a, 0x3af2, 0x0131, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x3d, 0x0e7d, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x40, 0x9a1c, 0x0000, 0x3a34, 0x010d, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x41, 0x9a1d, 0x0000, 0x3a34, 0x010e, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, /* ModeIdIndex = 0x10 */ - {0x43, 0x0a1c, 0x0306, 0x3a57, 0x0110, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x44, 0x0a1d, 0x0306, 0x3a57, 0x0111, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08, - 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08, - 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x02}, - {0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08, - 0x03, 0x00, 0x00, 0x07, 0x03}, - {0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08, - 0x04, 0x00, 0x00, 0x00, 0x04}, - {0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08, - 0x00, 0x00, 0x00, 0x04, 0x00}, - {0x5A, 0x021b, 0x0014, 0x3b83, 0x0138, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x3f}, /* ModeIdIndex = 0x20 */ - {0x5B, 0x0a1d, 0x0014, 0x3b83, 0x0135, 0x08, - 0x01, 0x00, 0x00, 0x04, 0x3f}, - {0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08, - 0x05, 0x00, 0x00, 0x07, 0x05}, - {0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08, - 0x06, 0x00, 0x00, 0x05, 0x06}, - {0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08, - 0x07, 0x00, 0x00, 0x07, 0x0e}, - {0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x16}, - {0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08, - 0x09, 0x00, 0x00, 0x00, 0x1e}, - {0x66, 0x0eff, 0x070a, 0x3af2, 0x013e, 0x08, - 0x0a, 0x00, 0x00, 0x00, 0x22}, /* mode 1600x1200 + {0x40, 0x9a1c, 0x0000, 0x00, 0x04, 0x00}, + {0x41, 0x9a1d, 0x0000, 0x00, 0x04, 0x00}, + {0x43, 0x0a1c, 0x0306, 0x06, 0x05, 0x06}, + {0x44, 0x0a1d, 0x0306, 0x06, 0x05, 0x06}, + {0x46, 0x2a1c, 0x0407, 0x07, 0x07, 0x0e}, + {0x47, 0x2a1d, 0x0407, 0x07, 0x07, 0x0e}, + {0x49, 0x0a3c, 0x0508, 0x08, 0x00, 0x16}, + {0x4a, 0x0a3d, 0x0508, 0x08, 0x00, 0x16}, + {0x4c, 0x0e7c, 0x0609, 0x09, 0x00, 0x1e}, + {0x4d, 0x0e7d, 0x0609, 0x09, 0x00, 0x1e}, + {0x50, 0x9a1b, 0x0001, 0x01, 0x04, 0x02}, + {0x51, 0xba1b, 0x0103, 0x03, 0x07, 0x03}, + {0x52, 0x9a1b, 0x0204, 0x04, 0x00, 0x04}, + {0x56, 0x9a1d, 0x0001, 0x01, 0x04, 0x02}, + {0x57, 0xba1d, 0x0103, 0x03, 0x07, 0x03}, + {0x58, 0x9a1d, 0x0204, 0x04, 0x00, 0x04}, + {0x59, 0x9a1b, 0x0000, 0x00, 0x04, 0x00}, + {0x5A, 0x021b, 0x0014, 0x01, 0x04, 0x3f}, + {0x5B, 0x0a1d, 0x0014, 0x01, 0x04, 0x3f}, + {0x5d, 0x0a1d, 0x0305, 0x05, 0x07, 0x05}, + {0x62, 0x0a3f, 0x0306, 0x06, 0x05, 0x06}, + {0x63, 0x2a3f, 0x0407, 0x07, 0x07, 0x0e}, + {0x64, 0x0a7f, 0x0508, 0x08, 0x00, 0x16}, + {0x65, 0x0eff, 0x0609, 0x09, 0x00, 0x1e}, + {0x66, 0x0eff, 0x070a, 0x0a, 0x00, 0x22}, /* mode 1600x1200 add CRT2MODE */ - {0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10, - 0x0b, 0x00, 0x00, 0x00, 0x29}, - {0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10, - 0x0c, 0x00, 0x00, 0x00, 0x2f}, - {0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, /* ModeIdIndex = 0x30 */ - {0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08, - 0x11, 0x00, 0x00, 0x00, 0x37}, - {0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08, - 0x12, 0x00, 0x00, 0x00, 0x3a}, - {0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08, - 0x10, 0x00, 0x00, 0x07, 0x34}, - {0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08, - 0x0f, 0x00, 0x00, 0x00, 0x1d}, - {0x20, 0x0e3b, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x21, 0x0e7d, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x22, 0x0eff, 0x0D16, 0x49e0, 0x0000, 0x08, - 0x16, 0x00, 0x00, 0x00, 0x43}, - {0x23, 0x0e3b, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x24, 0x0e7d, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x25, 0x0eff, 0x0614, 0x49d5, 0x0000, 0x08, - 0x14, 0x00, 0x00, 0x00, 0x41}, - {0x26, 0x063b, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, /* ModeIdIndex = 0x40 */ - {0x27, 0x067d, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, - {0x28, 0x06ff, 0x0c15, 0x49dc, 0x0000, 0x08, - 0x15, 0x00, 0x00, 0x00, 0x42}, - {0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -static struct SiS_StandTable_S XGI330_StandTable[] = { -/* MD_0_200 */ - { - 0x28, 0x18, 0x08, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_1_200 */ - { - 0x28, 0x18, 0x08, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_200 */ - { - 0x50, 0x18, 0x08, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_3_200 */ - { - 0x50, 0x18, 0x08, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_4 */ - { - 0x28, 0x18, 0x08, 0x4000, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff}, - {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, - 0xff} - }, -/* MD_5 */ - { - 0x28, 0x18, 0x08, 0x4000, - {0x09, 0x03, 0x00, 0x02}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2, - 0xff}, - {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x03, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00, - 0xff} - }, -/* MD_6 */ - { - 0x50, 0x18, 0x08, 0x4000, - {0x01, 0x01, 0x00, 0x06}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2, - 0xff}, - {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x01, 0x00, 0x01, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, - 0xff} - }, -/* MD_7 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x00, 0x03, 0x00, 0x03}, - 0xa6, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, - 0xff} - }, -/* MDA_DAC */ - { - 0x00, 0x00, 0x00, 0x0000, - {0x00, 0x00, 0x00, 0x15}, - 0x15, - {0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00, - 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15}, - {0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f} - }, -/* CGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x09, 0x15, 0x00}, - 0x10, - {0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, - 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a, - 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10, - 0x04}, - {0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04, - 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e, - 0x3e, 0x2b, 0x3b, 0x2f}, - {0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, - 0x3f} - }, -/* EGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x05, 0x15, 0x20}, - 0x30, - {0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18, - 0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38, - 0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12, - 0x06}, - {0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26, - 0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e, - 0x1e, 0x0b, 0x1b, 0x0f}, - {0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, - 0x3f} - }, -/* VGA_DAC */ - { - 0x00, 0x10, 0x04, 0x0114, - {0x11, 0x09, 0x15, 0x2a}, - 0x3a, - {0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05, - 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20, - 0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10, - 0x1f}, - {0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d, - 0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15, - 0x1c, 0x0e, 0x11, 0x15}, - {0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00, - 0x04} - }, - { - 0x08, 0x0c, 0x10, 0x0a08, - {0x0c, 0x0e, 0x10, 0x0b}, - 0x0c, - {0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, - 0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00, - 0x06}, - {0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08, - 0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00} - }, -/* MD_D */ - { - 0x28, 0x18, 0x08, 0x2000, - {0x09, 0x0f, 0x00, 0x06}, - 0x63, - {0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_E */ - { - 0x50, 0x18, 0x08, 0x4000, - {0x01, 0x0f, 0x00, 0x06}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, + {0x68, 0x067b, 0x080b, 0x0b, 0x00, 0x29}, + {0x69, 0x06fd, 0x080b, 0x0b, 0x00, 0x29}, + {0x6b, 0x07ff, 0x080b, 0x0b, 0x00, 0x29}, + {0x6c, 0x067b, 0x090c, 0x0c, 0x00, 0x2f}, + {0x6d, 0x06fd, 0x090c, 0x0c, 0x00, 0x2f}, + {0x6e, 0x07ff, 0x090c, 0x0c, 0x00, 0x2f}, + {0x70, 0x2a1b, 0x0410, 0x10, 0x07, 0x34}, + {0x71, 0x0a1b, 0x0511, 0x11, 0x00, 0x37}, + {0x74, 0x0a1d, 0x0511, 0x11, 0x00, 0x37}, + {0x75, 0x0a3d, 0x0612, 0x12, 0x00, 0x3a}, + {0x76, 0x2a1f, 0x0410, 0x10, 0x07, 0x34}, + {0x77, 0x0a1f, 0x0511, 0x11, 0x00, 0x37}, + {0x78, 0x0a3f, 0x0612, 0x12, 0x00, 0x3a}, + {0x79, 0x0a3b, 0x0612, 0x12, 0x00, 0x3a}, + {0x7a, 0x2a1d, 0x0410, 0x10, 0x07, 0x34}, + {0x7b, 0x0e3b, 0x060f, 0x0f, 0x00, 0x1d}, + {0x7c, 0x0e7d, 0x060f, 0x0f, 0x00, 0x1d}, + {0x7d, 0x0eff, 0x060f, 0x0f, 0x00, 0x1d}, + {0x20, 0x0e3b, 0x0D16, 0x16, 0x00, 0x43}, + {0x21, 0x0e7d, 0x0D16, 0x16, 0x00, 0x43}, + {0x22, 0x0eff, 0x0D16, 0x16, 0x00, 0x43}, + {0x23, 0x0e3b, 0x0614, 0x14, 0x00, 0x41}, + {0x24, 0x0e7d, 0x0614, 0x14, 0x00, 0x41}, + {0x25, 0x0eff, 0x0614, 0x14, 0x00, 0x41}, + {0x26, 0x063b, 0x0c15, 0x15, 0x00, 0x42}, + {0x27, 0x067d, 0x0c15, 0x15, 0x00, 0x42}, + {0x28, 0x06ff, 0x0c15, 0x15, 0x00, 0x42}, + {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00} +}; + +static struct SiS_StandTable_S XGI330_StandTable = { /* ExtVGATable */ - { - 0x00, 0x00, 0x00, 0x0000, - {0x01, 0x0f, 0x00, 0x0e}, - 0x23, - {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x01, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} - }, -/* ROM_SAVEPTR */ - { - 0x9f, 0x3b, 0x00, 0x00c0, - {0x00, 0x00, 0x00, 0x00}, - 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x3f, - 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1a, 0x00, 0xac, 0x3e, 0x00, 0xc0, - 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00} - }, -/* MD_F */ - { - 0x50, 0x18, 0x0e, 0x8000, - {0x01, 0x0f, 0x00, 0x06}, - 0xa2, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff}, - {0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x0b, 0x00, 0x05, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05, - 0xff} - }, -/* MD_10 */ - { - 0x50, 0x18, 0x0e, 0x8000, - {0x01, 0x0f, 0x00, 0x06}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_0_350 */ - { - 0x28, 0x18, 0x0e, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0xa3, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_1_350 */ - { - 0x28, 0x18, 0x0e, 0x0800, - {0x09, 0x03, 0x00, 0x02}, - 0xa3, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_350 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_3_350 */ - { - 0x50, 0x18, 0x0e, 0x1000, - {0x01, 0x03, 0x00, 0x02}, - 0xa3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x08, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_0_1_400 */ - { - 0x28, 0x18, 0x10, 0x0800, - {0x08, 0x03, 0x00, 0x02}, - 0x67, - {0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_2_3_400 */ - { - 0x50, 0x18, 0x10, 0x1000, - {0x00, 0x03, 0x00, 0x02}, - 0x67, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x0c, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, - 0xff} - }, -/* MD_7_400 */ - { - 0x50, 0x18, 0x10, 0x1000, - {0x00, 0x03, 0x00, 0x02}, - 0x66, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x0e, 0x00, 0x0f, 0x08}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00, - 0xff} - }, -/* MD_11 */ - { - 0x50, 0x1d, 0x10, 0xa000, - {0x01, 0x0f, 0x00, 0x06}, - 0xe3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3, - 0xff}, - {0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, - 0xff} - }, -/* ExtEGATable */ - { - 0x50, 0x1d, 0x10, 0xa000, - {0x01, 0x0f, 0x00, 0x06}, - 0xe3, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e, - 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x01, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, - 0xff} - }, -/* MD_13 */ - { - 0x28, 0x18, 0x08, 0x2000, - {0x01, 0x0f, 0x00, 0x0e}, - 0x63, - {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, - 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3, - 0xff}, - {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x41, 0x00, 0x0f, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, - 0xff} - } + 0x00, 0x00, 0x00, 0x0000, + {0x01, 0x0f, 0x00, 0x0e}, + 0x23, + {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, + 0xff}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x01, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, + 0xff} }; static struct XGI_TimingHStruct XGI_TimingH[1]; @@ -1143,7 +626,7 @@ static struct XGI330_LCDDataStruct XGI_NoScalingDatax75[] = { {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */ {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */ @@ -1153,7 +636,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */ {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */ @@ -1163,7 +646,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -1173,7 +656,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768Data[] = { {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 926, 865}, /* 01 (320x350,640x350) */ {18, 1346, 981, 940}, /* 02 (360x400,720x400) */ @@ -1184,7 +667,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 917, 854}, /* 01 (320x350,640x350) */ {18, 1346, 970, 907}, /* 02 (360x400,720x400) */ @@ -1195,7 +678,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -1206,7 +689,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */ {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */ @@ -1217,7 +700,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */ {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */ @@ -1228,7 +711,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -1239,7 +722,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1400x1050[] = { +static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */ {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */ @@ -1251,7 +734,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1400x1050[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */ {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */ @@ -1263,7 +746,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ @@ -1275,7 +758,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ @@ -1283,7 +766,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */ {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */ @@ -1296,7 +779,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */ {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -1309,7 +792,7 @@ static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */ {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */ @@ -1322,7 +805,7 @@ static struct XGI330_LCDDataDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct XGI_StLCDDes1600x1200Data[] = { +static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */ {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -1352,7 +835,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { }; /* ;;1024x768x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1024x768x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */ {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */ @@ -1363,7 +846,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1024x768x75[] = { }; /* ;;1024x768x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -1374,7 +857,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1024x768x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1280x1024x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */ {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -1386,7 +869,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddldes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -1398,7 +881,7 @@ static struct XGI330_LCDDataDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct xgifb_lcddes_1280x1024x75[] = { +static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */ {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -1410,7 +893,7 @@ static struct XGI330_LCDDataDesStruct xgifb_lcddes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI330_LCDDataDesStruct XGI_CetLCDDes1280x1024x75Data[] = { +static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index a7208e3..30cdd1a 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -66,8 +66,6 @@ struct xgi_hw_device_info { unsigned long ulVideoMemorySize; /* size, in bytes, of the memory on the board */ - unsigned char *pjIOAddress; /* base I/O address of VGA ports (0x3B0) */ - unsigned char jChipType; /* Used to Identify Graphics Chip */ /* defined in the data structure type */ /* "XGI_CHIP_TYPE" */ diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c index 917461c..4496737 100644 --- a/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/drivers/staging/zsmalloc/zsmalloc-main.c @@ -45,12 +45,12 @@ static DEFINE_PER_CPU(struct mapping_area, zs_map_area); static int is_first_page(struct page *page) { - return test_bit(PG_private, &page->flags); + return PagePrivate(page); } static int is_last_page(struct page *page) { - return test_bit(PG_private_2, &page->flags); + return PagePrivate2(page); } static void get_zspage_mapping(struct page *page, unsigned int *class_idx, @@ -180,7 +180,7 @@ out: * link together 3 PAGE_SIZE sized pages to form a zspage * since then we can perfectly fit in 8 such objects. */ -static int get_zspage_order(int class_size) +static int get_pages_per_zspage(int class_size) { int i, max_usedpc = 0; /* zspage order which gives maximum used size per KB */ @@ -368,7 +368,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) * identify the last page. */ error = -ENOMEM; - for (i = 0; i < class->zspage_order; i++) { + for (i = 0; i < class->pages_per_zspage; i++) { struct page *page, *prev_page; page = alloc_page(flags); @@ -377,7 +377,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) INIT_LIST_HEAD(&page->lru); if (i == 0) { /* first page */ - set_bit(PG_private, &page->flags); + SetPagePrivate(page); set_page_private(page, 0); first_page = page; first_page->inuse = 0; @@ -388,9 +388,8 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) page->first_page = first_page; if (i >= 2) list_add(&page->lru, &prev_page->lru); - if (i == class->zspage_order - 1) /* last page */ - set_bit(PG_private_2, &page->flags); - + if (i == class->pages_per_zspage - 1) /* last page */ + SetPagePrivate2(page); prev_page = page; } @@ -398,7 +397,7 @@ static struct page *alloc_zspage(struct size_class *class, gfp_t flags) first_page->freelist = obj_location_to_handle(first_page, 0); /* Maximum number of objects we can store in this zspage */ - first_page->objects = class->zspage_order * PAGE_SIZE / class->size; + first_page->objects = class->pages_per_zspage * PAGE_SIZE / class->size; error = 0; /* Success */ @@ -513,7 +512,7 @@ struct zs_pool *zs_create_pool(const char *name, gfp_t flags) class->size = size; class->index = i; spin_lock_init(&class->lock); - class->zspage_order = get_zspage_order(size); + class->pages_per_zspage = get_pages_per_zspage(size); } @@ -567,13 +566,9 @@ EXPORT_SYMBOL_GPL(zs_destroy_pool); * zs_malloc - Allocate block of given size from pool. * @pool: pool to allocate from * @size: size of block to allocate - * @page: page no. that holds the object - * @offset: location of object within page - * - * On success, <page, offset> identifies block allocated - * and 0 is returned. On failure, <page, offset> is set to - * 0 and -ENOMEM is returned. * + * On success, handle to the allocated object is returned, + * otherwise NULL. * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail. */ void *zs_malloc(struct zs_pool *pool, size_t size) @@ -604,7 +599,7 @@ void *zs_malloc(struct zs_pool *pool, size_t size) set_zspage_mapping(first_page, class->index, ZS_EMPTY); spin_lock(&class->lock); - class->pages_allocated += class->zspage_order; + class->pages_allocated += class->pages_per_zspage; } obj = first_page->freelist; @@ -659,7 +654,7 @@ void zs_free(struct zs_pool *pool, void *obj) fullness = fix_fullness_group(pool, first_page); if (fullness == ZS_EMPTY) - class->pages_allocated -= class->zspage_order; + class->pages_allocated -= class->pages_per_zspage; spin_unlock(&class->lock); @@ -668,6 +663,15 @@ void zs_free(struct zs_pool *pool, void *obj) } EXPORT_SYMBOL_GPL(zs_free); +/** + * zs_map_object - get address of allocated object from handle. + * @pool: pool from which the object was allocated + * @handle: handle returned from zs_malloc + * + * Before using an object allocated from zs_malloc, it must be mapped using + * this function. When done with the object, it must be unmapped using + * zs_unmap_object +*/ void *zs_map_object(struct zs_pool *pool, void *handle) { struct page *page; diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h index 92eefc6..6fd32a9 100644 --- a/drivers/staging/zsmalloc/zsmalloc_int.h +++ b/drivers/staging/zsmalloc/zsmalloc_int.h @@ -124,7 +124,7 @@ struct size_class { unsigned int index; /* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */ - int zspage_order; + int pages_per_zspage; spinlock_t lock; |