linux/arch/sh/boards/mach-landisk/psw.c
<<
>>
Prefs
   1/*
   2 * arch/sh/boards/landisk/psw.c
   3 *
   4 * push switch support for LANDISK and USL-5P
   5 *
   6 * Copyright (C) 2006-2007  Paul Mundt
   7 * Copyright (C) 2007  kogiidena
   8 *
   9 * This file is subject to the terms and conditions of the GNU General Public
  10 * License.  See the file "COPYING" in the main directory of this archive
  11 * for more details.
  12 */
  13#include <linux/io.h>
  14#include <linux/init.h>
  15#include <linux/interrupt.h>
  16#include <linux/platform_device.h>
  17#include <mach-landisk/mach/iodata_landisk.h>
  18#include <asm/push-switch.h>
  19
  20static irqreturn_t psw_irq_handler(int irq, void *arg)
  21{
  22        struct platform_device *pdev = arg;
  23        struct push_switch *psw = platform_get_drvdata(pdev);
  24        struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
  25        unsigned int sw_value;
  26        int ret = 0;
  27
  28        sw_value = (0x0ff & (~ctrl_inb(PA_STATUS)));
  29
  30        /* Nothing to do if there's no state change */
  31        if (psw->state) {
  32                ret = 1;
  33                goto out;
  34        }
  35
  36        /* Figure out who raised it */
  37        if (sw_value & (1 << psw_info->bit)) {
  38                psw->state = 1;
  39                mod_timer(&psw->debounce, jiffies + 50);
  40                ret = 1;
  41        }
  42
  43out:
  44        /* Clear the switch IRQs */
  45        ctrl_outb(0x00, PA_PWRINT_CLR);
  46
  47        return IRQ_RETVAL(ret);
  48}
  49
  50static struct resource psw_power_resources[] = {
  51        [0] = {
  52                .start = IRQ_POWER,
  53                .flags = IORESOURCE_IRQ,
  54       },
  55};
  56
  57static struct resource psw_usl5p_resources[] = {
  58        [0] = {
  59                .start = IRQ_BUTTON,
  60                .flags = IORESOURCE_IRQ,
  61        },
  62};
  63
  64static struct push_switch_platform_info psw_power_platform_data = {
  65        .name           = "psw_power",
  66        .bit            = 4,
  67        .irq_flags      = IRQF_SHARED,
  68        .irq_handler    = psw_irq_handler,
  69};
  70
  71static struct push_switch_platform_info psw1_platform_data = {
  72        .name           = "psw1",
  73        .bit            = 0,
  74        .irq_flags      = IRQF_SHARED,
  75        .irq_handler    = psw_irq_handler,
  76};
  77
  78static struct push_switch_platform_info psw2_platform_data = {
  79        .name           = "psw2",
  80        .bit            = 2,
  81        .irq_flags      = IRQF_SHARED,
  82        .irq_handler    = psw_irq_handler,
  83};
  84
  85static struct push_switch_platform_info psw3_platform_data = {
  86        .name           = "psw3",
  87        .bit            = 1,
  88        .irq_flags      = IRQF_SHARED,
  89        .irq_handler    = psw_irq_handler,
  90};
  91
  92static struct platform_device psw_power_switch_device = {
  93        .name           = "push-switch",
  94        .id             = 0,
  95        .num_resources  = ARRAY_SIZE(psw_power_resources),
  96        .resource       = psw_power_resources,
  97        .dev            = {
  98                .platform_data = &psw_power_platform_data,
  99        },
 100};
 101
 102static struct platform_device psw1_switch_device = {
 103        .name           = "push-switch",
 104        .id             = 1,
 105        .num_resources  = ARRAY_SIZE(psw_usl5p_resources),
 106        .resource       = psw_usl5p_resources,
 107        .dev            = {
 108                .platform_data = &psw1_platform_data,
 109        },
 110};
 111
 112static struct platform_device psw2_switch_device = {
 113        .name           = "push-switch",
 114        .id             = 2,
 115        .num_resources  = ARRAY_SIZE(psw_usl5p_resources),
 116        .resource       = psw_usl5p_resources,
 117        .dev            = {
 118                .platform_data = &psw2_platform_data,
 119        },
 120};
 121
 122static struct platform_device psw3_switch_device = {
 123        .name           = "push-switch",
 124        .id             = 3,
 125        .num_resources  = ARRAY_SIZE(psw_usl5p_resources),
 126        .resource       = psw_usl5p_resources,
 127        .dev = {
 128                .platform_data = &psw3_platform_data,
 129        },
 130};
 131
 132static struct platform_device *psw_devices[] = {
 133        &psw_power_switch_device,
 134        &psw1_switch_device,
 135        &psw2_switch_device,
 136        &psw3_switch_device,
 137};
 138
 139static int __init psw_init(void)
 140{
 141        return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
 142}
 143module_init(psw_init);
 144