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