^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Sony Programmable I/O Control Device driver for VAIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2001-2005 Stelian Pop <stelian@popies.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Copyright (C) 2000 Takaya Kinjo <t-kinjo@tc4.so-net.ne.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/sonypi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SONYPI_DRIVER_VERSION "1.26"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) MODULE_AUTHOR("Stelian Pop <stelian@popies.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MODULE_VERSION(SONYPI_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int minor = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) module_param(minor, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MODULE_PARM_DESC(minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "minor number of the misc device, default is -1 (automatic)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int verbose; /* = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) module_param(verbose, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int fnkeyinit; /* = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) module_param(fnkeyinit, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MODULE_PARM_DESC(fnkeyinit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "set this if your Fn keys do not generate any event");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int camera; /* = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) module_param(camera, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) MODULE_PARM_DESC(camera,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "set this if you have a MotionEye camera (PictureBook series)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int compat; /* = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) module_param(compat, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_PARM_DESC(compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) "set this if you want to enable backward compatibility mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static unsigned long mask = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) module_param(mask, ulong, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_PARM_DESC(mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "set this to the mask of event you want to enable (see doc)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int useinput = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) module_param(useinput, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MODULE_PARM_DESC(useinput,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "set this if you would like sonypi to feed events to the input subsystem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int check_ioport = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) module_param(check_ioport, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MODULE_PARM_DESC(check_ioport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) "set this to 0 if you think the automatic ioport check for sony-laptop is wrong");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define SONYPI_DEVICE_MODEL_TYPE1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define SONYPI_DEVICE_MODEL_TYPE2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SONYPI_DEVICE_MODEL_TYPE3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* type1 models use those */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define SONYPI_IRQ_PORT 0x8034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SONYPI_IRQ_SHIFT 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define SONYPI_TYPE1_BASE 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SONYPI_G10A (SONYPI_TYPE1_BASE+0x14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define SONYPI_TYPE1_REGION_SIZE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define SONYPI_TYPE1_EVTYPE_OFFSET 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* type2 series specifics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define SONYPI_SIRQ 0x9b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define SONYPI_SLOB 0x9c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define SONYPI_SHIB 0x9d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define SONYPI_TYPE2_REGION_SIZE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define SONYPI_TYPE2_EVTYPE_OFFSET 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* type3 series specifics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define SONYPI_TYPE3_BASE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define SONYPI_TYPE3_GID2 (SONYPI_TYPE3_BASE+0x48) /* 16 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define SONYPI_TYPE3_MISC (SONYPI_TYPE3_BASE+0x6d) /* 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define SONYPI_TYPE3_REGION_SIZE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define SONYPI_TYPE3_EVTYPE_OFFSET 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* battery / brightness addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define SONYPI_BAT_FLAGS 0x81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define SONYPI_LCD_LIGHT 0x96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define SONYPI_BAT1_PCTRM 0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define SONYPI_BAT1_LEFT 0xa2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define SONYPI_BAT1_MAXRT 0xa4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define SONYPI_BAT2_PCTRM 0xa8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define SONYPI_BAT2_LEFT 0xaa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define SONYPI_BAT2_MAXRT 0xac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define SONYPI_BAT1_MAXTK 0xb0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define SONYPI_BAT1_FULL 0xb2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define SONYPI_BAT2_MAXTK 0xb8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define SONYPI_BAT2_FULL 0xba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* FAN0 information (reverse engineered from ACPI tables) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define SONYPI_FAN0_STATUS 0x93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define SONYPI_TEMP_STATUS 0xC1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* ioports used for brightness and type2 events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SONYPI_DATA_IOPORT 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SONYPI_CST_IOPORT 0x66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* The set of possible ioports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct sonypi_ioport_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u16 port1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u16 port2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static struct sonypi_ioport_list sonypi_type1_ioport_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 0x10c0, 0x10c4 }, /* looks like the default on C1Vx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { 0x1080, 0x1084 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { 0x1090, 0x1094 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { 0x10a0, 0x10a4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { 0x10b0, 0x10b4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { 0x0, 0x0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static struct sonypi_ioport_list sonypi_type2_ioport_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { 0x1080, 0x1084 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) { 0x10a0, 0x10a4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) { 0x10c0, 0x10c4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { 0x10e0, 0x10e4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { 0x0, 0x0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* same as in type 2 models */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static struct sonypi_ioport_list *sonypi_type3_ioport_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) sonypi_type2_ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* The set of possible interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct sonypi_irq_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u16 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u16 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static struct sonypi_irq_list sonypi_type1_irq_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { 11, 0x2 }, /* IRQ 11, GO22=0,GO23=1 in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { 10, 0x1 }, /* IRQ 10, GO22=1,GO23=0 in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { 5, 0x0 }, /* IRQ 5, GO22=0,GO23=0 in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { 0, 0x3 } /* no IRQ, GO22=1,GO23=1 in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static struct sonypi_irq_list sonypi_type2_irq_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { 11, 0x80 }, /* IRQ 11, 0x80 in SIRQ in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { 10, 0x40 }, /* IRQ 10, 0x40 in SIRQ in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { 9, 0x20 }, /* IRQ 9, 0x20 in SIRQ in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { 6, 0x10 }, /* IRQ 6, 0x10 in SIRQ in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { 0, 0x00 } /* no IRQ, 0x00 in SIRQ in AML */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* same as in type2 models */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct sonypi_irq_list *sonypi_type3_irq_list = sonypi_type2_irq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define SONYPI_CAMERA_BRIGHTNESS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define SONYPI_CAMERA_CONTRAST 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define SONYPI_CAMERA_HUE 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define SONYPI_CAMERA_COLOR 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define SONYPI_CAMERA_SHARPNESS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define SONYPI_CAMERA_PICTURE 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define SONYPI_CAMERA_EXPOSURE_MASK 0xC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define SONYPI_CAMERA_WHITE_BALANCE_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define SONYPI_CAMERA_PICTURE_MODE_MASK 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define SONYPI_CAMERA_MUTE_MASK 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* the rest don't need a loop until not 0xff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define SONYPI_CAMERA_AGC 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define SONYPI_CAMERA_AGC_MASK 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define SONYPI_CAMERA_SHUTTER_MASK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define SONYPI_CAMERA_SHUTDOWN_REQUEST 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define SONYPI_CAMERA_CONTROL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define SONYPI_CAMERA_STATUS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define SONYPI_CAMERA_STATUS_READY 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define SONYPI_CAMERA_STATUS_POSITION 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define SONYPI_DIRECTION_BACKWARDS 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define SONYPI_CAMERA_REVISION 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define SONYPI_CAMERA_ROMVERSION 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Event masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define SONYPI_JOGGER_MASK 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define SONYPI_CAPTURE_MASK 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define SONYPI_FNKEY_MASK 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define SONYPI_BLUETOOTH_MASK 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define SONYPI_PKEY_MASK 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define SONYPI_BACK_MASK 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define SONYPI_HELP_MASK 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define SONYPI_LID_MASK 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define SONYPI_ZOOM_MASK 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define SONYPI_THUMBPHRASE_MASK 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define SONYPI_MEYE_MASK 0x00000400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define SONYPI_MEMORYSTICK_MASK 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define SONYPI_BATTERY_MASK 0x00001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define SONYPI_WIRELESS_MASK 0x00002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct sonypi_event {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u8 event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* The set of possible button release events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct sonypi_event sonypi_releaseev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) { 0x00, SONYPI_EVENT_ANYBUTTON_RELEASED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* The set of possible jogger events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static struct sonypi_event sonypi_joggerev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { 0x1f, SONYPI_EVENT_JOGDIAL_UP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { 0x01, SONYPI_EVENT_JOGDIAL_DOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { 0x5f, SONYPI_EVENT_JOGDIAL_UP_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 0x41, SONYPI_EVENT_JOGDIAL_DOWN_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { 0x1e, SONYPI_EVENT_JOGDIAL_FAST_UP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 0x02, SONYPI_EVENT_JOGDIAL_FAST_DOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { 0x5e, SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { 0x42, SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) { 0x1d, SONYPI_EVENT_JOGDIAL_VFAST_UP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) { 0x03, SONYPI_EVENT_JOGDIAL_VFAST_DOWN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) { 0x5d, SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { 0x43, SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) { 0x40, SONYPI_EVENT_JOGDIAL_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* The set of possible capture button events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static struct sonypi_event sonypi_captureev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) { 0x05, SONYPI_EVENT_CAPTURE_PARTIALPRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) { 0x07, SONYPI_EVENT_CAPTURE_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) { 0x01, SONYPI_EVENT_CAPTURE_PARTIALRELEASED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* The set of possible fnkeys events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static struct sonypi_event sonypi_fnkeyev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) { 0x10, SONYPI_EVENT_FNKEY_ESC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) { 0x11, SONYPI_EVENT_FNKEY_F1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) { 0x12, SONYPI_EVENT_FNKEY_F2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { 0x13, SONYPI_EVENT_FNKEY_F3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { 0x14, SONYPI_EVENT_FNKEY_F4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { 0x15, SONYPI_EVENT_FNKEY_F5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { 0x16, SONYPI_EVENT_FNKEY_F6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) { 0x17, SONYPI_EVENT_FNKEY_F7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) { 0x18, SONYPI_EVENT_FNKEY_F8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) { 0x19, SONYPI_EVENT_FNKEY_F9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) { 0x1a, SONYPI_EVENT_FNKEY_F10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) { 0x1b, SONYPI_EVENT_FNKEY_F11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) { 0x1c, SONYPI_EVENT_FNKEY_F12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { 0x1f, SONYPI_EVENT_FNKEY_RELEASED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) { 0x21, SONYPI_EVENT_FNKEY_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) { 0x22, SONYPI_EVENT_FNKEY_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) { 0x31, SONYPI_EVENT_FNKEY_D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) { 0x32, SONYPI_EVENT_FNKEY_E },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) { 0x33, SONYPI_EVENT_FNKEY_F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) { 0x34, SONYPI_EVENT_FNKEY_S },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 0x35, SONYPI_EVENT_FNKEY_B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 0x36, SONYPI_EVENT_FNKEY_ONLY },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* The set of possible program key events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static struct sonypi_event sonypi_pkeyev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { 0x01, SONYPI_EVENT_PKEY_P1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) { 0x02, SONYPI_EVENT_PKEY_P2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { 0x04, SONYPI_EVENT_PKEY_P3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) { 0x5c, SONYPI_EVENT_PKEY_P1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* The set of possible bluetooth events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static struct sonypi_event sonypi_blueev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) { 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { 0x59, SONYPI_EVENT_BLUETOOTH_ON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { 0x5a, SONYPI_EVENT_BLUETOOTH_OFF },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* The set of possible wireless events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static struct sonypi_event sonypi_wlessev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) { 0x59, SONYPI_EVENT_WIRELESS_ON },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* The set of possible back button events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static struct sonypi_event sonypi_backev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) { 0x20, SONYPI_EVENT_BACK_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* The set of possible help button events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static struct sonypi_event sonypi_helpev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { 0x3b, SONYPI_EVENT_HELP_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* The set of possible lid events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static struct sonypi_event sonypi_lidev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) { 0x51, SONYPI_EVENT_LID_CLOSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) { 0x50, SONYPI_EVENT_LID_OPENED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* The set of possible zoom events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static struct sonypi_event sonypi_zoomev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) { 0x39, SONYPI_EVENT_ZOOM_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* The set of possible thumbphrase events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static struct sonypi_event sonypi_thumbphraseev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { 0x3a, SONYPI_EVENT_THUMBPHRASE_PRESSED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* The set of possible motioneye camera events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static struct sonypi_event sonypi_meyeev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { 0x00, SONYPI_EVENT_MEYE_FACE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) { 0x01, SONYPI_EVENT_MEYE_OPPOSITE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* The set of possible memorystick events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static struct sonypi_event sonypi_memorystickev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) { 0x53, SONYPI_EVENT_MEMORYSTICK_INSERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) { 0x54, SONYPI_EVENT_MEMORYSTICK_EJECT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* The set of possible battery events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static struct sonypi_event sonypi_batteryev[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { 0x20, SONYPI_EVENT_BATTERY_INSERT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) { 0x30, SONYPI_EVENT_BATTERY_REMOVE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { 0, 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static struct sonypi_eventtypes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) unsigned long mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct sonypi_event * events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) } sonypi_eventtypes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) { SONYPI_DEVICE_MODEL_TYPE1, 0, 0xffffffff, sonypi_releaseev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) { SONYPI_DEVICE_MODEL_TYPE1, 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_LID_MASK, sonypi_lidev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) { SONYPI_DEVICE_MODEL_TYPE1, 0x60, SONYPI_CAPTURE_MASK, sonypi_captureev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) { SONYPI_DEVICE_MODEL_TYPE1, 0x10, SONYPI_JOGGER_MASK, sonypi_joggerev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) { SONYPI_DEVICE_MODEL_TYPE1, 0x20, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_PKEY_MASK, sonypi_pkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { SONYPI_DEVICE_MODEL_TYPE1, 0x30, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { SONYPI_DEVICE_MODEL_TYPE1, 0x40, SONYPI_BATTERY_MASK, sonypi_batteryev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) { SONYPI_DEVICE_MODEL_TYPE2, 0, 0xffffffff, sonypi_releaseev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) { SONYPI_DEVICE_MODEL_TYPE2, 0x38, SONYPI_LID_MASK, sonypi_lidev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_JOGGER_MASK, sonypi_joggerev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { SONYPI_DEVICE_MODEL_TYPE2, 0x61, SONYPI_CAPTURE_MASK, sonypi_captureev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_BLUETOOTH_MASK, sonypi_blueev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { SONYPI_DEVICE_MODEL_TYPE2, 0x08, SONYPI_PKEY_MASK, sonypi_pkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { SONYPI_DEVICE_MODEL_TYPE2, 0x11, SONYPI_BACK_MASK, sonypi_backev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_HELP_MASK, sonypi_helpev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { SONYPI_DEVICE_MODEL_TYPE2, 0x21, SONYPI_ZOOM_MASK, sonypi_zoomev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { SONYPI_DEVICE_MODEL_TYPE2, 0x20, SONYPI_THUMBPHRASE_MASK, sonypi_thumbphraseev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { SONYPI_DEVICE_MODEL_TYPE2, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { SONYPI_DEVICE_MODEL_TYPE2, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { SONYPI_DEVICE_MODEL_TYPE3, 0, 0xffffffff, sonypi_releaseev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) { SONYPI_DEVICE_MODEL_TYPE3, 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) { SONYPI_DEVICE_MODEL_TYPE3, 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { SONYPI_DEVICE_MODEL_TYPE3, 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #define SONYPI_BUF_SIZE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* Correspondance table between sonypi events and input layer events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int sonypiev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int inputev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } sonypi_inputkeys[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) { SONYPI_EVENT_FNKEY_ONLY, KEY_FN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) { SONYPI_EVENT_FNKEY_1, KEY_FN_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) { SONYPI_EVENT_FNKEY_2, KEY_FN_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) { SONYPI_EVENT_FNKEY_D, KEY_FN_D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) { SONYPI_EVENT_FNKEY_E, KEY_FN_E },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) { SONYPI_EVENT_FNKEY_F, KEY_FN_F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { SONYPI_EVENT_FNKEY_S, KEY_FN_S },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { SONYPI_EVENT_FNKEY_B, KEY_FN_B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) { SONYPI_EVENT_PKEY_P1, KEY_PROG1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { SONYPI_EVENT_PKEY_P2, KEY_PROG2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) { SONYPI_EVENT_PKEY_P3, KEY_PROG3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) { SONYPI_EVENT_BACK_PRESSED, KEY_BACK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) { SONYPI_EVENT_HELP_PRESSED, KEY_HELP },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) { 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) struct sonypi_keypress {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct input_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static struct sonypi_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct pci_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u16 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u16 bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) u16 ioport1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) u16 ioport2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u16 region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u16 evtype_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int camera_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int bluetooth_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct kfifo fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) spinlock_t fifo_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) wait_queue_head_t fifo_proc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct fasync_struct *fifo_async;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct input_dev *input_jog_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct input_dev *input_key_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct work_struct input_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct kfifo input_fifo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) spinlock_t input_fifo_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } sonypi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define ITERATIONS_LONG 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #define ITERATIONS_SHORT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) #define wait_on_command(quiet, command, iterations) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) unsigned int n = iterations; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) while (--n && (command)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) udelay(1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!n && (verbose || !quiet)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) printk(KERN_WARNING "sonypi command failed at %s : %s (line %d)\n", __FILE__, __func__, __LINE__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #define SONYPI_ACPI_ACTIVE (!acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #define SONYPI_ACPI_ACTIVE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #endif /* CONFIG_ACPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static struct acpi_device *sonypi_acpi_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int acpi_driver_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int sonypi_ec_write(u8 addr, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (SONYPI_ACPI_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ec_write(addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) outb_p(0x81, SONYPI_CST_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) outb_p(addr, SONYPI_DATA_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) outb_p(value, SONYPI_DATA_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int sonypi_ec_read(u8 addr, u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (SONYPI_ACPI_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return ec_read(addr, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) wait_on_command(1, inb_p(SONYPI_CST_IOPORT) & 3, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) outb_p(0x80, SONYPI_CST_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) outb_p(addr, SONYPI_DATA_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) wait_on_command(0, inb_p(SONYPI_CST_IOPORT) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) *value = inb_p(SONYPI_DATA_IOPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int ec_read16(u8 addr, u16 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) u8 val_lb, val_hb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (sonypi_ec_read(addr, &val_lb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (sonypi_ec_read(addr + 1, &val_hb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *value = val_lb | (val_hb << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Initializes the device - this comes from the AML code in the ACPI bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static void sonypi_type1_srs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) v = (v & 0xFFFF0000) | ((u32) sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) v = (v & 0xFFF0FFFF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) (((u32) sonypi_device.ioport1 ^ sonypi_device.ioport2) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) v = inl(SONYPI_IRQ_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) v &= ~(((u32) 0x3) << SONYPI_IRQ_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) v |= (((u32) sonypi_device.bits) << SONYPI_IRQ_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) outl(v, SONYPI_IRQ_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) v = (v & 0xFF1FFFFF) | 0x00C00000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void sonypi_type2_srs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (sonypi_ec_write(SONYPI_SHIB, (sonypi_device.ioport1 & 0xFF00) >> 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (sonypi_ec_write(SONYPI_SLOB, sonypi_device.ioport1 & 0x00FF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (sonypi_ec_write(SONYPI_SIRQ, sonypi_device.bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static void sonypi_type3_srs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u16 v16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u8 v8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* This model type uses the same initialization of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * the embedded controller as the type2 models. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) sonypi_type2_srs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /* Initialization of PCI config space of the LPC interface bridge. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) v16 = (sonypi_device.ioport1 & 0xFFF0) | 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, v16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) pci_read_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, &v8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) v8 = (v8 & 0xCF) | 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pci_write_config_byte(sonypi_device.dev, SONYPI_TYPE3_MISC, v8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Disables the device - this comes from the AML code in the ACPI bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static void sonypi_type1_dis(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) pci_read_config_dword(sonypi_device.dev, SONYPI_G10A, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) v = v & 0xFF3FFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) pci_write_config_dword(sonypi_device.dev, SONYPI_G10A, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) v = inl(SONYPI_IRQ_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) v |= (0x3 << SONYPI_IRQ_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) outl(v, SONYPI_IRQ_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void sonypi_type2_dis(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (sonypi_ec_write(SONYPI_SHIB, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) if (sonypi_ec_write(SONYPI_SLOB, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (sonypi_ec_write(SONYPI_SIRQ, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) printk(KERN_WARNING "ec_write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static void sonypi_type3_dis(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sonypi_type2_dis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) pci_write_config_word(sonypi_device.dev, SONYPI_TYPE3_GID2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static u8 sonypi_call1(u8 dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) u8 v1, v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) outb(dev, sonypi_device.ioport2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) v1 = inb_p(sonypi_device.ioport2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) v2 = inb_p(sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static u8 sonypi_call2(u8 dev, u8 fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u8 v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) outb(dev, sonypi_device.ioport2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) outb(fn, sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) v1 = inb_p(sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static u8 sonypi_call3(u8 dev, u8 fn, u8 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) u8 v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) outb(dev, sonypi_device.ioport2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) outb(fn, sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) wait_on_command(0, inb_p(sonypi_device.ioport2) & 2, ITERATIONS_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) outb(v, sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) v1 = inb_p(sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* Get brightness, hue etc. Unreliable... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static u8 sonypi_read(u8 fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) u8 v1, v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) int n = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) while (n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) v1 = sonypi_call2(0x8f, fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) v2 = sonypi_call2(0x8f, fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (v1 == v2 && v1 != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* Set brightness, hue etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static void sonypi_set(u8 fn, u8 v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) wait_on_command(0, sonypi_call3(0x90, fn, v), ITERATIONS_SHORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /* Tests if the camera is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int sonypi_camera_ready(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) v = sonypi_call2(0x8f, SONYPI_CAMERA_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return (v != 0xff && (v & SONYPI_CAMERA_STATUS_READY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* Turns the camera off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static void sonypi_camera_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sonypi_set(SONYPI_CAMERA_PICTURE, SONYPI_CAMERA_MUTE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!sonypi_device.camera_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) sonypi_call2(0x91, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) sonypi_device.camera_power = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* Turns the camera on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static void sonypi_camera_on(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (sonypi_device.camera_power)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) for (j = 5; j > 0; j--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) while (sonypi_call2(0x91, 0x1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sonypi_call1(0x93);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) for (i = 400; i > 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (sonypi_camera_ready())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (j == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) printk(KERN_WARNING "sonypi: failed to power on camera\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sonypi_set(0x10, 0x5a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) sonypi_device.camera_power = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /* sets the bluetooth subsystem power state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static void sonypi_setbluetoothpower(u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) state = !!state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (sonypi_device.bluetooth_power == state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) sonypi_call2(0x96, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) sonypi_call1(0x82);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) sonypi_device.bluetooth_power = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static void input_keyrelease(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct sonypi_keypress kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) sizeof(kp), &sonypi_device.input_fifo_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) == sizeof(kp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) input_report_key(kp.dev, kp.key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) input_sync(kp.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static void sonypi_report_input_event(u8 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct input_dev *jog_dev = sonypi_device.input_jog_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct input_dev *key_dev = sonypi_device.input_key_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct sonypi_keypress kp = { NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case SONYPI_EVENT_JOGDIAL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) input_report_rel(jog_dev, REL_WHEEL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) input_sync(jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case SONYPI_EVENT_JOGDIAL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) input_report_rel(jog_dev, REL_WHEEL, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) input_sync(jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case SONYPI_EVENT_JOGDIAL_PRESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) kp.key = BTN_MIDDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) kp.dev = jog_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) case SONYPI_EVENT_FNKEY_RELEASED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* Nothing, not all VAIOs generate this event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (event == sonypi_inputkeys[i].sonypiev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) kp.dev = key_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) kp.key = sonypi_inputkeys[i].inputev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (kp.dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) input_report_key(kp.dev, kp.key, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) input_sync(kp.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) kfifo_in_locked(&sonypi_device.input_fifo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (unsigned char *)&kp, sizeof(kp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) &sonypi_device.input_fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) schedule_work(&sonypi_device.input_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Interrupt handler: some event is available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static irqreturn_t sonypi_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) u8 v1, v2, event = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) v1 = inb_p(sonypi_device.ioport1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) v2 = inb_p(sonypi_device.ioport1 + sonypi_device.evtype_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) for (i = 0; sonypi_eventtypes[i].model; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (sonypi_device.model != sonypi_eventtypes[i].model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if ((v2 & sonypi_eventtypes[i].data) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) sonypi_eventtypes[i].data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!(mask & sonypi_eventtypes[i].mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) for (j = 0; sonypi_eventtypes[i].events[j].event; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (v1 == sonypi_eventtypes[i].events[j].data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) event = sonypi_eventtypes[i].events[j].event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) "sonypi: unknown event port1=0x%02x,port2=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) v1, v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* We need to return IRQ_HANDLED here because there *are*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * events belonging to the sonypi device we don't know about,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * but we still don't want those to pollute the logs... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (verbose > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (useinput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) sonypi_report_input_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) sizeof(event), &sonypi_device.fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) wake_up_interruptible(&sonypi_device.fifo_proc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static int sonypi_misc_fasync(int fd, struct file *filp, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static int sonypi_misc_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) mutex_lock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) sonypi_device.open_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) mutex_unlock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static int sonypi_misc_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) mutex_lock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) /* Flush input queue on first open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (!sonypi_device.open_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) kfifo_reset(&sonypi_device.fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sonypi_device.open_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) mutex_unlock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) size_t count, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if ((kfifo_len(&sonypi_device.fifo) == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) (file->f_flags & O_NONBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) kfifo_len(&sonypi_device.fifo) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) while (ret < count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) &sonypi_device.fifo_lock) == sizeof(c))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (put_user(c, buf++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ret++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (ret > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct inode *inode = file_inode(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) inode->i_atime = current_time(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static __poll_t sonypi_misc_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) poll_wait(file, &sonypi_device.fifo_proc_list, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (kfifo_len(&sonypi_device.fifo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static long sonypi_misc_ioctl(struct file *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) long ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) u8 val8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) u16 val16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) mutex_lock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) case SONYPI_IOCGBRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (sonypi_ec_read(SONYPI_LCD_LIGHT, &val8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (copy_to_user(argp, &val8, sizeof(val8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) case SONYPI_IOCSBRT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (copy_from_user(&val8, argp, sizeof(val8))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (sonypi_ec_write(SONYPI_LCD_LIGHT, val8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) case SONYPI_IOCGBAT1CAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ec_read16(SONYPI_BAT1_FULL, &val16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (copy_to_user(argp, &val16, sizeof(val16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) case SONYPI_IOCGBAT1REM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (ec_read16(SONYPI_BAT1_LEFT, &val16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (copy_to_user(argp, &val16, sizeof(val16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) case SONYPI_IOCGBAT2CAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (ec_read16(SONYPI_BAT2_FULL, &val16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (copy_to_user(argp, &val16, sizeof(val16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case SONYPI_IOCGBAT2REM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (ec_read16(SONYPI_BAT2_LEFT, &val16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (copy_to_user(argp, &val16, sizeof(val16)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) case SONYPI_IOCGBATFLAGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (sonypi_ec_read(SONYPI_BAT_FLAGS, &val8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) val8 &= 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (copy_to_user(argp, &val8, sizeof(val8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) case SONYPI_IOCGBLUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) val8 = sonypi_device.bluetooth_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (copy_to_user(argp, &val8, sizeof(val8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) case SONYPI_IOCSBLUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (copy_from_user(&val8, argp, sizeof(val8))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) sonypi_setbluetoothpower(val8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* FAN Controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) case SONYPI_IOCGFAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (sonypi_ec_read(SONYPI_FAN0_STATUS, &val8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (copy_to_user(argp, &val8, sizeof(val8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) case SONYPI_IOCSFAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (copy_from_user(&val8, argp, sizeof(val8))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (sonypi_ec_write(SONYPI_FAN0_STATUS, val8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* GET Temperature (useful under APM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) case SONYPI_IOCGTEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (sonypi_ec_read(SONYPI_TEMP_STATUS, &val8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (copy_to_user(argp, &val8, sizeof(val8)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) mutex_unlock(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static const struct file_operations sonypi_misc_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .read = sonypi_misc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .poll = sonypi_misc_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .open = sonypi_misc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .release = sonypi_misc_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .fasync = sonypi_misc_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .unlocked_ioctl = sonypi_misc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static struct miscdevice sonypi_misc_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .name = "sonypi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .fops = &sonypi_misc_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static void sonypi_enable(unsigned int camera_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) switch (sonypi_device.model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) case SONYPI_DEVICE_MODEL_TYPE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sonypi_type1_srs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) case SONYPI_DEVICE_MODEL_TYPE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) sonypi_type2_srs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) case SONYPI_DEVICE_MODEL_TYPE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) sonypi_type3_srs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) sonypi_call1(0x82);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) sonypi_call2(0x81, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) sonypi_call1(compat ? 0x92 : 0x82);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* Enable ACPI mode to get Fn key events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) outb(0xf0, 0xb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (camera && camera_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) sonypi_camera_on();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static int sonypi_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) sonypi_call2(0x81, 0); /* make sure we don't get any more events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (camera)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) sonypi_camera_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* disable ACPI mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) outb(0xf1, 0xb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) switch (sonypi_device.model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) case SONYPI_DEVICE_MODEL_TYPE1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) sonypi_type1_dis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) case SONYPI_DEVICE_MODEL_TYPE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) sonypi_type2_dis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) case SONYPI_DEVICE_MODEL_TYPE3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sonypi_type3_dis();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static int sonypi_acpi_add(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) sonypi_acpi_device = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) strcpy(acpi_device_name(device), "Sony laptop hotkeys");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) strcpy(acpi_device_class(device), "sony/hotkey");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static int sonypi_acpi_remove(struct acpi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) sonypi_acpi_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static const struct acpi_device_id sonypi_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {"SNY6001", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) {"", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static struct acpi_driver sonypi_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .name = "sonypi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .class = "hkey",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .ids = sonypi_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .add = sonypi_acpi_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .remove = sonypi_acpi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static int sonypi_create_input_devices(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct input_dev *jog_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct input_dev *key_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (!jog_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) jog_dev->name = "Sony Vaio Jogdial";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) jog_dev->id.bustype = BUS_ISA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) jog_dev->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) sonypi_device.input_key_dev = key_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (!key_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) goto err_free_jogdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) key_dev->name = "Sony Vaio Keys";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) key_dev->id.bustype = BUS_ISA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) key_dev->id.vendor = PCI_VENDOR_ID_SONY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) key_dev->dev.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /* Initialize the Input Drivers: special keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) key_dev->evbit[0] = BIT_MASK(EV_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (sonypi_inputkeys[i].inputev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) error = input_register_device(jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto err_free_keydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) error = input_register_device(key_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto err_unregister_jogdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) err_unregister_jogdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) input_unregister_device(jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* Set to NULL so we don't free it again below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) jog_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) err_free_keydev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) input_free_device(key_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) sonypi_device.input_key_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) err_free_jogdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) input_free_device(jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) sonypi_device.input_jog_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static int sonypi_setup_ioports(struct sonypi_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) const struct sonypi_ioport_list *ioport_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* try to detect if sony-laptop is being used and thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * has already requested one of the known ioports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * As in the deprecated check_region this is racy has we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * multiple ioports available and one of them can be requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * between this check and the subsequent request. Anyway, as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * attempt to be some more user-friendly as we currently are,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * this is enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) const struct sonypi_ioport_list *check = ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) while (check_ioport && check->port1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (!request_region(check->port1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) sonypi_device.region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) "Sony Programmable I/O Device Check")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) printk(KERN_ERR "sonypi: ioport 0x%.4x busy, using sony-laptop? "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) "if not use check_ioport=0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) check->port1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) release_region(check->port1, sonypi_device.region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) check++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) while (ioport_list->port1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (request_region(ioport_list->port1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) sonypi_device.region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) "Sony Programmable I/O Device")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) dev->ioport1 = ioport_list->port1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) dev->ioport2 = ioport_list->port2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ioport_list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static int sonypi_setup_irq(struct sonypi_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) const struct sonypi_irq_list *irq_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) while (irq_list->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (!request_irq(irq_list->irq, sonypi_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) IRQF_SHARED, "sonypi", sonypi_irq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dev->irq = irq_list->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) dev->bits = irq_list->bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) irq_list++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static void sonypi_display_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) printk(KERN_INFO "sonypi: detected type%d model, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) "verbose = %d, fnkeyinit = %s, camera = %s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) sonypi_device.model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) fnkeyinit ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) camera ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) compat ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) useinput ? "on" : "off",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) SONYPI_ACPI_ACTIVE ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sonypi_device.irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) sonypi_device.ioport1, sonypi_device.ioport2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (minor == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) printk(KERN_INFO "sonypi: device allocated minor is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) sonypi_misc_device.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static int sonypi_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) const struct sonypi_ioport_list *ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) const struct sonypi_irq_list *irq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct pci_dev *pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) printk(KERN_WARNING "sonypi: please try the sony-laptop module instead "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) "and report failures, see also "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) spin_lock_init(&sonypi_device.fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) init_waitqueue_head(&sonypi_device.fifo_proc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) mutex_init(&sonypi_device.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) sonypi_device.bluetooth_power = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (pcidev && pci_enable_device(pcidev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) printk(KERN_ERR "sonypi: pci_enable_device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) goto err_put_pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) sonypi_device.dev = pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ioport_list = sonypi_type1_ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) irq_list = sonypi_type1_irq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) } else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) ioport_list = sonypi_type2_ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) irq_list = sonypi_type2_irq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) ioport_list = sonypi_type3_ioport_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) irq_list = sonypi_type3_irq_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) error = sonypi_setup_ioports(&sonypi_device, ioport_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) printk(KERN_ERR "sonypi: failed to request ioports\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) goto err_disable_pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) error = sonypi_setup_irq(&sonypi_device, irq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) printk(KERN_ERR "sonypi: request_irq failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) goto err_free_ioports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (minor != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) sonypi_misc_device.minor = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) error = misc_register(&sonypi_misc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) printk(KERN_ERR "sonypi: misc_register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) goto err_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) sonypi_display_info();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (useinput) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) error = sonypi_create_input_devices(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) "sonypi: failed to create input devices\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto err_miscdev_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) spin_lock_init(&sonypi_device.input_fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) goto err_inpdev_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) INIT_WORK(&sonypi_device.input_work, input_keyrelease);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) sonypi_enable(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) err_inpdev_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) input_unregister_device(sonypi_device.input_key_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) input_unregister_device(sonypi_device.input_jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) err_miscdev_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) misc_deregister(&sonypi_misc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) err_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) free_irq(sonypi_device.irq, sonypi_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) err_free_ioports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) release_region(sonypi_device.ioport1, sonypi_device.region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) err_disable_pcidev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (pcidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) pci_disable_device(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) err_put_pcidev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) pci_dev_put(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) kfifo_free(&sonypi_device.fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) static int sonypi_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) sonypi_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) synchronize_irq(sonypi_device.irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) flush_work(&sonypi_device.input_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (useinput) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) input_unregister_device(sonypi_device.input_key_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) input_unregister_device(sonypi_device.input_jog_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) kfifo_free(&sonypi_device.input_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) misc_deregister(&sonypi_misc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) free_irq(sonypi_device.irq, sonypi_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) release_region(sonypi_device.ioport1, sonypi_device.region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (sonypi_device.dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) pci_disable_device(sonypi_device.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) pci_dev_put(sonypi_device.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) kfifo_free(&sonypi_device.fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static int old_camera_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static int sonypi_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) old_camera_power = sonypi_device.camera_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) sonypi_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) static int sonypi_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) sonypi_enable(old_camera_power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) static SIMPLE_DEV_PM_OPS(sonypi_pm, sonypi_suspend, sonypi_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) #define SONYPI_PM (&sonypi_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) #define SONYPI_PM NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static void sonypi_shutdown(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) sonypi_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) static struct platform_driver sonypi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .name = "sonypi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .pm = SONYPI_PM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .probe = sonypi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .remove = sonypi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .shutdown = sonypi_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static struct platform_device *sonypi_platform_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) static const struct dmi_system_id sonypi_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .ident = "Sony Vaio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .ident = "Sony Vaio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static int __init sonypi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) "sonypi: Sony Programmable I/O Controller Driver v%s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) SONYPI_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (!dmi_check_system(sonypi_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) error = platform_driver_register(&sonypi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) sonypi_platform_device = platform_device_alloc("sonypi", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) if (!sonypi_platform_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) goto err_driver_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) error = platform_device_add(sonypi_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto err_free_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) acpi_driver_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) err_free_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) platform_device_put(sonypi_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) err_driver_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) platform_driver_unregister(&sonypi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static void __exit sonypi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) if (acpi_driver_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) acpi_bus_unregister_driver(&sonypi_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) platform_device_unregister(sonypi_platform_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) platform_driver_unregister(&sonypi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) printk(KERN_INFO "sonypi: removed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) module_init(sonypi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) module_exit(sonypi_exit);