* Re: [PATCH] input/speaker: additional clicks and tones for future accessibility
From: Dmitry Torokhov @ 2014-12-03 19:58 UTC (permalink / raw)
To: Karl Dahlke; +Cc: vojtech, linux-input
In-Reply-To: <20141102001740.eklhad@comcast.net>
Hi Karl,
On Tue, Dec 02, 2014 at 12:17:40AM -0500, Karl Dahlke wrote:
> From: Karl Dahlke <eklhad@gmail.com>
>
> Add clicks, tones, and tone sequences to the pc speaker.
>
> The speaker driver can play a tone at a specified frequency,
> or the standard control G bell,
> which is a special case of TONE at 1000 hz 0.1 seconds.
> Add kd_mkpulse() to generate a soft click.
> This is introduced to support accessibility modules and adapters in the future.
> It is a means to an end.
> With this function in place, a module can easily provide soft clicks,
> i.e. audible feedback, whenever a key is depressed,
> or when that keystroke is echoed on screen.
> This allows a blind user, for example, to have rapid feedback while typing,
> even if he is, at the same time, listening to text that is already on screen.
> It is faster and more convenient than having characters echoed verbally.
> And it works all the time, even if speech or braille is not working
> for whatever reason.
>
> Also add the function kd_mknotes,
> which plays a series of tones in the background.
> Of course this can already be done with kd_mksound and timers,
> but why should everyone reinvent the wheel?
> It is better to write the function once, properly, in the kernel,
> and let modules use it thereafter.
> Again, this is a means to an end.
> Accessibility modules can generate rapid sequences of notes
> to indicate various conditions, sometimes error conditions,
> especially if speech or braille is not working.
> These notes may be the only feedback the user has to diagnose the problem.
> This may be useful to other developers in other situations as well.
>
> Finally add kd_mksteps to run something like a chromatic scale,
> from one frequency to another in specified steps.
> The half-tone scale, with a step of 6%, starting at middle C, is approximately
> kd_mksteps(260, 530, 6, 150);
I have exactly the same response as a year earlier:
"I do not think it is a good idea to add SND_PULSE as it can be easily
implemented by SND_TONE with the additional benefit that parameters of
the click can be adjusted. Also, if clicking is done elsewhere, it would
work with other speaker drivers besides pcspkr.
...
[re kd_mknotes] Can it be put into a library instead? Especially given
David's work on trying to push the VT code out of the kernel. Also, what
if you want clicks to go through sound card and not the speaker
interface?"
In other words, I'd rather have it all be done in userpsace by a daemon
that listens to all keystrokes and emits notes or clicks or something
else via whatever sound device is present on the system, be it a PC
speaker, SPARC speaker, a sound card, or maybe something else.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH] Input: Initialize atomic_t variables by -1
From: Aniroop Mathur @ 2014-12-03 20:16 UTC (permalink / raw)
To: dmitry.torokhov, dtor, linux-input; +Cc: aniroop.mathur, a.mathur
This patch initializes atomic_t variables by -1 in order to avoid
extra subtraction operation performed everytime for allocation of
an input device.
Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
---
drivers/input/gameport/gameport.c | 4 ++--
drivers/input/joystick/xpad.c | 4 ++--
drivers/input/misc/ims-pcu.c | 4 ++--
drivers/input/serio/serio.c | 4 ++--
drivers/input/serio/serio_raw.c | 4 ++--
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 24c41ba..d8371e8 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -490,14 +490,14 @@ EXPORT_SYMBOL(gameport_set_phys);
*/
static void gameport_init_port(struct gameport *gameport)
{
- static atomic_t gameport_no = ATOMIC_INIT(0);
+ static atomic_t gameport_no = ATOMIC_INIT(-1);
__module_get(THIS_MODULE);
mutex_init(&gameport->drv_mutex);
device_initialize(&gameport->dev);
dev_set_name(&gameport->dev, "gameport%lu",
- (unsigned long)atomic_inc_return(&gameport_no) - 1);
+ (unsigned long)atomic_inc_return(&gameport_no));
gameport->dev.bus = &gameport_bus;
gameport->dev.release = gameport_release_port;
if (gameport->parent)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 177602c..64dc7cb 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -850,7 +850,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe(struct usb_xpad *xpad)
{
- static atomic_t led_seq = ATOMIC_INIT(0);
+ static atomic_t led_seq = ATOMIC_INIT(-1);
long led_no;
struct xpad_led *led;
struct led_classdev *led_cdev;
@@ -863,7 +863,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
if (!led)
return -ENOMEM;
- led_no = (long)atomic_inc_return(&led_seq) - 1;
+ led_no = (long)atomic_inc_return(&led_seq);
snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
led->xpad = xpad;
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 719410f..69caee9 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
{
- static atomic_t device_no = ATOMIC_INIT(0);
+ static atomic_t device_no = ATOMIC_INIT(-1);
const struct ims_pcu_device_info *info;
int error;
@@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
}
/* Device appears to be operable, complete initialization */
- pcu->device_no = atomic_inc_return(&device_no) - 1;
+ pcu->device_no = atomic_inc_return(&device_no);
/*
* PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index b29134d..21698cc 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev)
*/
static void serio_init_port(struct serio *serio)
{
- static atomic_t serio_no = ATOMIC_INIT(0);
+ static atomic_t serio_no = ATOMIC_INIT(-1);
__module_get(THIS_MODULE);
@@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio)
mutex_init(&serio->drv_mutex);
device_initialize(&serio->dev);
dev_set_name(&serio->dev, "serio%ld",
- (long)atomic_inc_return(&serio_no) - 1);
+ (long)atomic_inc_return(&serio_no));
serio->dev.bus = &serio_bus;
serio->dev.release = serio_release_port;
serio->dev.groups = serio_device_attr_groups;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index c9a02fe..71ef5d6 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
{
- static atomic_t serio_raw_no = ATOMIC_INIT(0);
+ static atomic_t serio_raw_no = ATOMIC_INIT(-1);
struct serio_raw *serio_raw;
int err;
@@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
}
snprintf(serio_raw->name, sizeof(serio_raw->name),
- "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1);
+ "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
kref_init(&serio_raw->kref);
INIT_LIST_HEAD(&serio_raw->client_list);
init_waitqueue_head(&serio_raw->wait);
--
1.9.1
^ permalink raw reply related
* [PATCH] Input: Initialize device count variables by -1
From: Aniroop Mathur @ 2014-12-03 20:39 UTC (permalink / raw)
To: dmitry.torokhov, dtor, linux-input; +Cc: aniroop.mathur, a.mathur
This patch initializes input device count variables by -1 in order
to avoid extra subtraction operation performed everytime for
allocation of an input device.
Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
---
drivers/input/gameport/gameport.c | 4 ++--
drivers/input/joystick/xpad.c | 4 ++--
drivers/input/misc/ims-pcu.c | 4 ++--
drivers/input/serio/serio.c | 4 ++--
drivers/input/serio/serio_raw.c | 4 ++--
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 24c41ba..d8371e8 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -490,14 +490,14 @@ EXPORT_SYMBOL(gameport_set_phys);
*/
static void gameport_init_port(struct gameport *gameport)
{
- static atomic_t gameport_no = ATOMIC_INIT(0);
+ static atomic_t gameport_no = ATOMIC_INIT(-1);
__module_get(THIS_MODULE);
mutex_init(&gameport->drv_mutex);
device_initialize(&gameport->dev);
dev_set_name(&gameport->dev, "gameport%lu",
- (unsigned long)atomic_inc_return(&gameport_no) - 1);
+ (unsigned long)atomic_inc_return(&gameport_no));
gameport->dev.bus = &gameport_bus;
gameport->dev.release = gameport_release_port;
if (gameport->parent)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 177602c..64dc7cb 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -850,7 +850,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
static int xpad_led_probe(struct usb_xpad *xpad)
{
- static atomic_t led_seq = ATOMIC_INIT(0);
+ static atomic_t led_seq = ATOMIC_INIT(-1);
long led_no;
struct xpad_led *led;
struct led_classdev *led_cdev;
@@ -863,7 +863,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
if (!led)
return -ENOMEM;
- led_no = (long)atomic_inc_return(&led_seq) - 1;
+ led_no = (long)atomic_inc_return(&led_seq);
snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
led->xpad = xpad;
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 719410f..69caee9 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
{
- static atomic_t device_no = ATOMIC_INIT(0);
+ static atomic_t device_no = ATOMIC_INIT(-1);
const struct ims_pcu_device_info *info;
int error;
@@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
}
/* Device appears to be operable, complete initialization */
- pcu->device_no = atomic_inc_return(&device_no) - 1;
+ pcu->device_no = atomic_inc_return(&device_no);
/*
* PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index b29134d..21698cc 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev)
*/
static void serio_init_port(struct serio *serio)
{
- static atomic_t serio_no = ATOMIC_INIT(0);
+ static atomic_t serio_no = ATOMIC_INIT(-1);
__module_get(THIS_MODULE);
@@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio)
mutex_init(&serio->drv_mutex);
device_initialize(&serio->dev);
dev_set_name(&serio->dev, "serio%ld",
- (long)atomic_inc_return(&serio_no) - 1);
+ (long)atomic_inc_return(&serio_no));
serio->dev.bus = &serio_bus;
serio->dev.release = serio_release_port;
serio->dev.groups = serio_device_attr_groups;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index c9a02fe..71ef5d6 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
{
- static atomic_t serio_raw_no = ATOMIC_INIT(0);
+ static atomic_t serio_raw_no = ATOMIC_INIT(-1);
struct serio_raw *serio_raw;
int err;
@@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
}
snprintf(serio_raw->name, sizeof(serio_raw->name),
- "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1);
+ "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
kref_init(&serio_raw->kref);
INIT_LIST_HEAD(&serio_raw->client_list);
init_waitqueue_head(&serio_raw->wait);
--
1.9.1
^ permalink raw reply related
* [PATCH] input/speaker: additional clicks and tones for future...
From: Karl Dahlke @ 2014-12-03 21:02 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: vojtech, linux-input
In-Reply-To: <20141203195811.GB16951@dtor-ws>
Thank you for your thoughtful reply.
> I do not think it is a good idea to add SND_PULSE as it can be easily
> implemented by SND_TONE.
It isn't that simple.
Example: if a tone is playing for any reason the clicks do not interrupt
the tone. (It would sound terrible, I've tried it).
Clicks and tones are different in spirit and in implementation,
almost orthogonal, and my code manages all this.
> Also, what if you want clicks to go through sound card and not the speaker
But you see, in my world, I precisely don't want that to happen,
because sometimes the sound card isn't working.
There are lots of reasons a sound card might not work,
alsa and modules and pulseaudio are more finicky than you might think,
not to mention the speech adapters that sit on top of them.
If any link in this chain is broken, I get no speech, period.
If I then don't get the clicks or tones either, I'm really lost at sea.
Thus the modules that I write,
and that other people write as well,
specifically send small diagnostics through the pc speaker,
because that just might be all the feedback we have.
Here is a good example, grub, or maybe it's grub2,
can't reasonably be expected to work through a sound card,
so it can actually generate morse code at the pc speaker to help us load
the desired OS.
It's just a different philosophy that we have I guess.
So instead of reinventing these routines over and over I thought it might be
useful to have some of this common functionality in the pcspkr driver
in the kernel.
I mean it's already halfway there, this is just the other half.
All managed just like tones are managed today.
It's just the icing on the cake.
Respectfully,
Karl Dahlke
^ permalink raw reply
* Re: [PATCH] Input: Initialize device count variables by -1
From: Dmitry Torokhov @ 2014-12-03 22:35 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: linux-input, a.mathur
In-Reply-To: <1417639146-3494-1-git-send-email-aniroop.mathur@gmail.com>
On Thu, Dec 04, 2014 at 02:09:06AM +0530, Aniroop Mathur wrote:
> This patch initializes input device count variables by -1 in order
> to avoid extra subtraction operation performed everytime for
> allocation of an input device.
>
> Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
Applied, thank you.
> ---
> drivers/input/gameport/gameport.c | 4 ++--
> drivers/input/joystick/xpad.c | 4 ++--
> drivers/input/misc/ims-pcu.c | 4 ++--
> drivers/input/serio/serio.c | 4 ++--
> drivers/input/serio/serio_raw.c | 4 ++--
> 5 files changed, 10 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
> index 24c41ba..d8371e8 100644
> --- a/drivers/input/gameport/gameport.c
> +++ b/drivers/input/gameport/gameport.c
> @@ -490,14 +490,14 @@ EXPORT_SYMBOL(gameport_set_phys);
> */
> static void gameport_init_port(struct gameport *gameport)
> {
> - static atomic_t gameport_no = ATOMIC_INIT(0);
> + static atomic_t gameport_no = ATOMIC_INIT(-1);
>
> __module_get(THIS_MODULE);
>
> mutex_init(&gameport->drv_mutex);
> device_initialize(&gameport->dev);
> dev_set_name(&gameport->dev, "gameport%lu",
> - (unsigned long)atomic_inc_return(&gameport_no) - 1);
> + (unsigned long)atomic_inc_return(&gameport_no));
> gameport->dev.bus = &gameport_bus;
> gameport->dev.release = gameport_release_port;
> if (gameport->parent)
> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
> index 177602c..64dc7cb 100644
> --- a/drivers/input/joystick/xpad.c
> +++ b/drivers/input/joystick/xpad.c
> @@ -850,7 +850,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
>
> static int xpad_led_probe(struct usb_xpad *xpad)
> {
> - static atomic_t led_seq = ATOMIC_INIT(0);
> + static atomic_t led_seq = ATOMIC_INIT(-1);
> long led_no;
> struct xpad_led *led;
> struct led_classdev *led_cdev;
> @@ -863,7 +863,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
> if (!led)
> return -ENOMEM;
>
> - led_no = (long)atomic_inc_return(&led_seq) - 1;
> + led_no = (long)atomic_inc_return(&led_seq);
>
> snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
> led->xpad = xpad;
> diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
> index 719410f..69caee9 100644
> --- a/drivers/input/misc/ims-pcu.c
> +++ b/drivers/input/misc/ims-pcu.c
> @@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
>
> static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
> {
> - static atomic_t device_no = ATOMIC_INIT(0);
> + static atomic_t device_no = ATOMIC_INIT(-1);
>
> const struct ims_pcu_device_info *info;
> int error;
> @@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
> }
>
> /* Device appears to be operable, complete initialization */
> - pcu->device_no = atomic_inc_return(&device_no) - 1;
> + pcu->device_no = atomic_inc_return(&device_no);
>
> /*
> * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor
> diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
> index b29134d..21698cc 100644
> --- a/drivers/input/serio/serio.c
> +++ b/drivers/input/serio/serio.c
> @@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev)
> */
> static void serio_init_port(struct serio *serio)
> {
> - static atomic_t serio_no = ATOMIC_INIT(0);
> + static atomic_t serio_no = ATOMIC_INIT(-1);
>
> __module_get(THIS_MODULE);
>
> @@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio)
> mutex_init(&serio->drv_mutex);
> device_initialize(&serio->dev);
> dev_set_name(&serio->dev, "serio%ld",
> - (long)atomic_inc_return(&serio_no) - 1);
> + (long)atomic_inc_return(&serio_no));
> serio->dev.bus = &serio_bus;
> serio->dev.release = serio_release_port;
> serio->dev.groups = serio_device_attr_groups;
> diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
> index c9a02fe..71ef5d6 100644
> --- a/drivers/input/serio/serio_raw.c
> +++ b/drivers/input/serio/serio_raw.c
> @@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
>
> static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
> {
> - static atomic_t serio_raw_no = ATOMIC_INIT(0);
> + static atomic_t serio_raw_no = ATOMIC_INIT(-1);
> struct serio_raw *serio_raw;
> int err;
>
> @@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
> }
>
> snprintf(serio_raw->name, sizeof(serio_raw->name),
> - "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1);
> + "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
> kref_init(&serio_raw->kref);
> INIT_LIST_HEAD(&serio_raw->client_list);
> init_waitqueue_head(&serio_raw->wait);
> --
> 1.9.1
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH] input/speaker: additional clicks and tones for future...
From: Dmitry Torokhov @ 2014-12-03 22:52 UTC (permalink / raw)
To: Karl Dahlke; +Cc: vojtech, linux-input
In-Reply-To: <20141103160258.eklhad@comcast.net>
On Wed, Dec 03, 2014 at 04:02:58PM -0500, Karl Dahlke wrote:
> Thank you for your thoughtful reply.
>
> > I do not think it is a good idea to add SND_PULSE as it can be easily
> > implemented by SND_TONE.
>
> It isn't that simple.
> Example: if a tone is playing for any reason the clicks do not interrupt
> the tone. (It would sound terrible, I've tried it).
> Clicks and tones are different in spirit and in implementation,
> almost orthogonal, and my code manages all this.
Even if it sounds horrible why would not you want feedback for key press
if there is tone? Would you not rather want to know that key press has
been registered?
>
> > Also, what if you want clicks to go through sound card and not the speaker
>
> But you see, in my world, I precisely don't want that to happen,
> because sometimes the sound card isn't working.
I understand that you might not want to use sound card, that does not
mean that nobody else would now want it. There are boxes without pcspkr
or where speaker is provided by different module.
> There are lots of reasons a sound card might not work,
> alsa and modules and pulseaudio are more finicky than you might think,
> not to mention the speech adapters that sit on top of them.
> If any link in this chain is broken, I get no speech, period.
> If I then don't get the clicks or tones either, I'm really lost at sea.
You should be able to work directly with ALSA though, right? That would
cut some of the stack away.
> Thus the modules that I write,
> and that other people write as well,
> specifically send small diagnostics through the pc speaker,
> because that just might be all the feedback we have.
> Here is a good example, grub, or maybe it's grub2,
> can't reasonably be expected to work through a sound card,
> so it can actually generate morse code at the pc speaker to help us load
> the desired OS.
But grub is not an OS, so naturally it does not have sound card
support. It also does not support any of the haptic devices that might
be connected to the box but that does not mean that haptic devices are
not suitable as feedback devices.
> It's just a different philosophy that we have I guess.
> So instead of reinventing these routines over and over I thought it might be
> useful to have some of this common functionality in the pcspkr driver
> in the kernel.
> I mean it's already halfway there, this is just the other half.
> All managed just like tones are managed today.
> It's just the icing on the cake.
>
I am sorry, but I still believe that doing this in pcspkr/tty would be
doing this at the wrong level and userspace solution would be the right
one. It does not need to use real sound card if you prefer not to, but
I do not think it should prohibit using it or any other device that can
provide adequate feedback.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH 2/3] drivers:input:ps2 Added sunxi A20 ps2 driver, changed makefile and Kconfig
From: vishnupatekar @ 2014-12-03 22:53 UTC (permalink / raw)
To: maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
msalter-H+wXaHxf7aLQT0dZR+AlfA, ralf-6z/3iImG2C8G8FEW9MqTrA,
jdelvare-l3A5Bk7waGM, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w, vishnupatekar
---
drivers/input/serio/Kconfig | 9 ++
drivers/input/serio/Makefile | 1 +
drivers/input/serio/sunxi-ps2.c | 305 +++++++++++++++++++++++++++++++++++++++
3 files changed, 315 insertions(+)
create mode 100644 drivers/input/serio/sunxi-ps2.c
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index bc2d474..1a86e41 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -281,4 +281,13 @@ config HYPERV_KEYBOARD
To compile this driver as a module, choose M here: the module will
be called hyperv_keyboard.
+config SERIO_SUNXI_PS2
+ tristate "Allwinner Sun7i-A20 PS/2 controller"
+ default m
+ help
+ Say Y here if you have Sun7i-A20 Allwinner PS/2 ports.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sunxi-ps2.
+
endif
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
index 815d874..0fa0f78 100644
--- a/drivers/input/serio/Makefile
+++ b/drivers/input/serio/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o
obj-$(CONFIG_SERIO_APBPS2) += apbps2.o
obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o
obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o
+obj-$(CONFIG_SERIO_SUNXI_PS2) += sunxi-ps2.o
diff --git a/drivers/input/serio/sunxi-ps2.c b/drivers/input/serio/sunxi-ps2.c
new file mode 100644
index 0000000..ccd7b29
--- /dev/null
+++ b/drivers/input/serio/sunxi-ps2.c
@@ -0,0 +1,305 @@
+/*
+ * sunxi-ps2.c Support for Allwinner A20 PS2 host controller
+ *
+ * Author: Aaron.maoye <leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org>
+ * Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Based on sunxi-ps2.c 3.0 kernel
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/serio.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#define DRIVER_NAME "sunxi-ps2"
+
+#define RESSIZE(res) (((res)->end - (res)->start)+1)
+
+#define SW_PS2_GCTRL (0x00)
+#define SW_PS2_DATA (0x04)
+#define SW_PS2_LCTRL (0x08)
+#define SW_PS2_LSTAT (0x0c)
+#define SW_PS2_FCTRL (0x10)
+#define SW_PS2_FSTAT (0x14)
+#define SW_PS2_CLKDR (0x18)
+
+/* SW_PS2_GCTRL */
+#define SWPS2_BUSEN (1 << 0)
+#define SWPS2_MASTER (1 << 1)
+#define SWPS2_RESET (1 << 2)
+#define SWPS2_INTEN (1 << 3)
+#define SWPS2_INTFLAG (1 << 3)
+
+/* SW_PS2_LCTRL */
+#define SWPS2_LCTL_NOACK (0x0 << 18)
+#define SWPS2_LCTL_TXDTOEN (0x1 << 8)
+#define SWPS2_LCTL_STOPERREN (0x1 << 3)
+#define SWPS2_LCTL_ACKERREN (0x1 << 2)
+#define SWPS2_LCTL_PARERREN (0x1 << 1)
+#define SWPS2_LCTL_RXDTOEN (0x1 << 0)
+
+/* SW_PS2_FSTAT */
+#define SWPS2_FSTA_RXRDY (1 << 0)
+#define SWPS2_FSTA_RXOF (1 << 1)
+#define SWPS2_FSTA_RXUF (1 << 2)
+#define SWPS2_FSTA_TXRDY (1 << 8)
+#define SWPS2_FSTA_TXOF (1 << 9)
+#define SWPS2_FSTA_TXUF (1 << 10)
+
+#define SW_PS2_SAMPLE_CLK (1000000)
+#define SW_PS2_SCLK (125000)
+
+struct sunxips2data {
+ int irq;
+ spinlock_t ps2_lock;
+ void __iomem *base_address; /* virt address of control registers*/
+ struct serio *serio; /* serio*/
+ struct device *dev;
+ struct clk *pclk;
+};
+
+/*********************/
+/* Interrupt handler */
+/*********************/
+static irqreturn_t sunxips2_interrupt(int irq, void *dev_id)
+{
+ struct sunxips2data *drvdata = dev_id;
+ u32 intr_status;
+ u32 fifo_status;
+ unsigned char byte;
+ u32 rval;
+ u32 error = 0;
+
+ spin_lock(&drvdata->ps2_lock);
+
+ /* Get the PS/2 interrupts and clear them */
+ intr_status = readl(drvdata->base_address + SW_PS2_LSTAT);
+ fifo_status = readl(drvdata->base_address + SW_PS2_FSTAT);
+
+ /*Check Line Status Register*/
+ if (intr_status & 0x10f) {
+ if (intr_status & 0x08)
+ dev_info(drvdata->dev, "PS/2 Stop Bit Error!");
+ if (intr_status & 0x04)
+ dev_info(drvdata->dev, "PS/2 Acknowledge Error!\n");
+ if (intr_status & 0x02)
+ dev_info(drvdata->dev, "PS/2 Parity Error!\n");
+ if (intr_status & 0x100)
+ dev_info(drvdata->dev, "PS/2 Transmit Data Timeout!\n");
+ if (intr_status & 0x01)
+ dev_info(drvdata->dev, "PS/2 Receive Data Timeout!\n");
+
+ writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4, drvdata->base_address + SW_PS2_GCTRL);/*reset PS/2 controller*/
+ writel(0x10f, drvdata->base_address + SW_PS2_LSTAT);
+
+ error = 1;
+ }
+
+ /*Check FIFO Status Register*/
+ if (fifo_status & 0x0606) {
+ if (fifo_status & 0x400)
+ dev_info(drvdata->dev, "PS/2 Tx FIFO Underflow!\n");
+ if (fifo_status & 0x200)
+ dev_info(drvdata->dev, "PS/2 Tx FIFO Overflow!\n");
+ if (fifo_status & 0x04)
+ dev_info(drvdata->dev, "PS/2 Rx FIFO Underflow!\n");
+ if (fifo_status & 0x02)
+ dev_info(drvdata->dev, "PS/2 Rx FIFO Overflow!\n");
+
+ writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4, drvdata->base_address + SW_PS2_GCTRL); /*reset PS/2 controller*/
+ writel(0x707, drvdata->base_address + SW_PS2_FSTAT);
+ error = 1;
+ }
+
+ rval = (fifo_status >> 16) & 0x3;
+ while (!error && rval--) {
+ byte = readl(drvdata->base_address + SW_PS2_DATA) & 0xff;
+ dev_info(drvdata->dev, "PS/2 Receive %02x\n", byte);
+ serio_interrupt(drvdata->serio, byte, 0);
+ }
+
+ writel(intr_status, drvdata->base_address + SW_PS2_LSTAT);
+ writel(fifo_status, drvdata->base_address + SW_PS2_FSTAT);
+
+ spin_unlock(&drvdata->ps2_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sunxips2_open(struct serio *pserio)
+{
+ struct sunxips2data *drvdata = pserio->port_data;
+ u32 src_clk = 0;
+ u32 clk_scdf;
+ u32 clk_pcdf;
+ u32 rval;
+
+ /*Set Line Control And Enable Interrupt*/
+ rval = SWPS2_LCTL_TXDTOEN|SWPS2_LCTL_STOPERREN|SWPS2_LCTL_ACKERREN|SWPS2_LCTL_PARERREN|SWPS2_LCTL_RXDTOEN;
+ writel(rval, drvdata->base_address + SW_PS2_LCTRL);
+
+ /*Reset FIFO*/
+ writel(0x3<<16 | 0x607, drvdata->base_address + SW_PS2_FCTRL);
+
+ src_clk = clk_get_rate(drvdata->pclk);
+
+ if (!src_clk) {
+ dev_info(drvdata->dev, "w_ps2c_set_sclk error, source clock is 0.");
+ return -1;
+ }
+
+ /*Set Clock Divider Register*/
+ clk_scdf = ((src_clk + (SW_PS2_SAMPLE_CLK>>1)) / SW_PS2_SAMPLE_CLK - 1);
+ clk_pcdf = ((SW_PS2_SAMPLE_CLK + (SW_PS2_SCLK>>1)) / SW_PS2_SCLK - 1);
+ rval = (clk_scdf<<8) | clk_pcdf;/* | (PS2_DEBUG_SEL<<16);*/
+ writel(rval, drvdata->base_address + SW_PS2_CLKDR);
+
+ /*Set Global Control Register*/
+ rval = SWPS2_RESET|SWPS2_INTEN|SWPS2_MASTER|SWPS2_BUSEN;
+ writel(rval, drvdata->base_address + SW_PS2_GCTRL);
+
+ udelay(100);
+
+ return 0;
+}
+
+static void sunxips2_close(struct serio *pserio)
+{
+ struct sunxips2data *drvdata = pserio->port_data;
+
+ spin_lock(&drvdata->ps2_lock);
+ /* Disable the PS2 interrupts */
+ writel(0, drvdata->base_address + SW_PS2_GCTRL);
+ spin_unlock(&drvdata->ps2_lock);
+}
+
+static int sunxips2_write(struct serio *pserio, unsigned char val)
+{
+ struct sunxips2data *drvdata = (struct sunxips2data *)pserio->port_data;
+ u32 timeout = 10000;
+
+ do {
+ if (readl(drvdata->base_address + SW_PS2_FSTAT) & SWPS2_FSTA_TXRDY) {
+ writel(val, drvdata->base_address + SW_PS2_DATA);
+ return 0;
+ }
+ } while (timeout--);
+
+ return -1;
+}
+
+static int sunxips2_probe(struct platform_device *ofdev)
+{
+ struct resource *res; /* IO mem resources */
+ struct sunxips2data *drvdata;
+ struct serio *serio;
+ struct device *dev = &ofdev->dev;
+ unsigned int irq;
+ int error;
+
+ drvdata = devm_kzalloc(dev, sizeof(struct sunxips2data), GFP_KERNEL);
+ serio = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
+ if (!drvdata || !serio)
+ error = -ENOMEM;
+
+ /* Request clock */
+ drvdata->pclk = clk_get(dev, NULL);
+ if (IS_ERR(drvdata->pclk))
+ dev_dbg(dev, "couldn't get clock %li\n",
+ PTR_ERR(drvdata->pclk));
+
+ if (!IS_ERR(drvdata->pclk)) {
+ error = clk_prepare_enable(drvdata->pclk);
+ if (error < 0) {
+ dev_err(dev, "failed to enable clock %d\n", error);
+ return error;
+ }
+ }
+
+ /* IO */
+ res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
+ drvdata->base_address = devm_ioremap_resource(dev, res);
+ if (IS_ERR(drvdata->base_address)) {
+ dev_err(dev, "failed to map registers\n");
+ error = PTR_ERR(drvdata->base_address);
+ }
+
+ serio->id.type = SERIO_8042;
+ serio->write = sunxips2_write;
+ serio->open = sunxips2_open;
+ serio->close = sunxips2_close;
+ serio->port_data = drvdata;
+ serio->dev.parent = dev;
+ strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
+ strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
+
+ platform_set_drvdata(ofdev, drvdata);
+ serio_register_port(serio);
+
+ /* Get IRQ for the device */
+ irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+ if (!irq) {
+ dev_err(dev, "no IRQ found\n");
+ return -ENODEV;
+ }
+
+ drvdata->irq = irq;
+ drvdata->serio = serio;
+ drvdata->dev = dev;
+ error = devm_request_any_context_irq(drvdata->dev, drvdata->irq, &sunxips2_interrupt, 0,
+ DRIVER_NAME, drvdata);
+ if (error) {
+ dev_err(drvdata->dev,
+ "Couldn't allocate interrupt %d : error: %d\n", drvdata->irq, error);
+ return error;
+ }
+ return 0; /* success */
+}
+
+static int sunxips2_remove(struct platform_device *of_dev)
+{
+ struct sunxips2data *drvdata = platform_get_drvdata(of_dev);
+
+ if (!IS_ERR(drvdata->pclk)) {
+ clk_disable_unprepare(drvdata->pclk);
+ clk_put(drvdata->pclk);
+ }
+ serio_unregister_port(drvdata->serio);
+ mdelay(2);
+ return 0;
+}
+
+/* Match table for of_platform binding */
+static const struct of_device_id sunxips2_of_match[] = {
+ { .compatible = "allwinner,sun7i-a20-ps2", },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, sunxips2_of_match);
+
+/*platform driver structure*/
+static struct platform_driver sunxips2_of_driver = {
+ .probe = sunxips2_probe,
+ .remove = sunxips2_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sunxips2_of_match,
+ },
+};
+module_platform_driver(sunxips2_of_driver);
+
+MODULE_AUTHOR("Aaron.maoye<leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org, "
+ "Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("Sunxi PS/2 driver");
+MODULE_LICENSE("GPL");
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v2 2/2] Input: amikbd - Allocate temporary keymap buffer on the stack
From: Dmitry Torokhov @ 2014-12-03 22:59 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-input, linux-m68k
In-Reply-To: <1417339820-5285-2-git-send-email-geert@linux-m68k.org>
On Sun, Nov 30, 2014 at 10:30:20AM +0100, Geert Uytterhoeven wrote:
> Allocate the temporary buffer needed for initialization of the console
> keyboard maps (512 bytes, as NR_KEYS = 256) on the stack instead of
> statically, to reduce kernel size.
>
> add/remove: 0/1 grow/shrink: 0/0 up/down: 0/-512 (-512)
> function old new delta
> temp_map 512 - -512
So because it is marked __initdata and is placed into a separate
section we have to allocate the space in the image?
Anyway, applied both, thank you.
>
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
> ---
> v2:
> - Allocate temp_map[] on the stack instead of using kmalloc().
> ---
> drivers/input/keyboard/amikbd.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
> index 4f81e65d9e35cb7d..60580d8104b9f970 100644
> --- a/drivers/input/keyboard/amikbd.c
> +++ b/drivers/input/keyboard/amikbd.c
> @@ -147,10 +147,10 @@ static unsigned char amikbd_keycode[0x78] __initdata = {
>
> static void __init amikbd_init_console_keymaps(void)
> {
> + unsigned short temp_map[NR_KEYS];
> int i, j;
>
> for (i = 0; i < MAX_NR_KEYMAPS; i++) {
> - static u_short temp_map[NR_KEYS] __initdata;
> if (!key_maps[i])
> continue;
> memset(temp_map, 0, sizeof(temp_map));
> --
> 1.9.1
>
--
Dmitry
^ permalink raw reply
* Re: [PATCH 2/3] drivers:input:ps2 Added sunxi A20 ps2 driver, changed makefile and Kconfig
From: Dmitry Torokhov @ 2014-12-03 23:23 UTC (permalink / raw)
To: vishnupatekar
Cc: maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r,
msalter-H+wXaHxf7aLQT0dZR+AlfA, ralf-6z/3iImG2C8G8FEW9MqTrA,
jdelvare-l3A5Bk7waGM, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1417647224-27950-1-git-send-email-VishnuPatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Thu, Dec 04, 2014 at 04:23:44AM +0530, vishnupatekar wrote:
> ---
> drivers/input/serio/Kconfig | 9 ++
> drivers/input/serio/Makefile | 1 +
> drivers/input/serio/sunxi-ps2.c | 305 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 315 insertions(+)
> create mode 100644 drivers/input/serio/sunxi-ps2.c
>
> diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
> index bc2d474..1a86e41 100644
> --- a/drivers/input/serio/Kconfig
> +++ b/drivers/input/serio/Kconfig
> @@ -281,4 +281,13 @@ config HYPERV_KEYBOARD
> To compile this driver as a module, choose M here: the module will
> be called hyperv_keyboard.
>
> +config SERIO_SUNXI_PS2
> + tristate "Allwinner Sun7i-A20 PS/2 controller"
> + default m
Why default m? Default should be n. Also it seems it has to depend on
OF. And what about depending on <arch> || COMPILE_TEST?
> + help
> + Say Y here if you have Sun7i-A20 Allwinner PS/2 ports.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called sunxi-ps2.
> +
> endif
> diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
> index 815d874..0fa0f78 100644
> --- a/drivers/input/serio/Makefile
> +++ b/drivers/input/serio/Makefile
> @@ -29,3 +29,4 @@ obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o
> obj-$(CONFIG_SERIO_APBPS2) += apbps2.o
> obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o
> obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o
> +obj-$(CONFIG_SERIO_SUNXI_PS2) += sunxi-ps2.o
> diff --git a/drivers/input/serio/sunxi-ps2.c b/drivers/input/serio/sunxi-ps2.c
> new file mode 100644
> index 0000000..ccd7b29
> --- /dev/null
> +++ b/drivers/input/serio/sunxi-ps2.c
> @@ -0,0 +1,305 @@
> +/*
> + * sunxi-ps2.c Support for Allwinner A20 PS2 host controller
No file names in sources please.
> + *
> + * Author: Aaron.maoye <leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org>
> + * Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> + * Based on sunxi-ps2.c 3.0 kernel
> + *
> +*/
> +
> +#include <linux/module.h>
> +#include <linux/serio.h>
> +#include <linux/interrupt.h>
> +#include <linux/errno.h>
> +#include <linux/slab.h>
> +#include <linux/list.h>
> +#include <linux/io.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +
> +#define DRIVER_NAME "sunxi-ps2"
> +
> +#define RESSIZE(res) (((res)->end - (res)->start)+1)
I am sure we have something generic for it, no?
> +
> +#define SW_PS2_GCTRL (0x00)
> +#define SW_PS2_DATA (0x04)
> +#define SW_PS2_LCTRL (0x08)
> +#define SW_PS2_LSTAT (0x0c)
> +#define SW_PS2_FCTRL (0x10)
> +#define SW_PS2_FSTAT (0x14)
> +#define SW_PS2_CLKDR (0x18)
> +
> +/* SW_PS2_GCTRL */
> +#define SWPS2_BUSEN (1 << 0)
> +#define SWPS2_MASTER (1 << 1)
> +#define SWPS2_RESET (1 << 2)
> +#define SWPS2_INTEN (1 << 3)
> +#define SWPS2_INTFLAG (1 << 3)
> +
> +/* SW_PS2_LCTRL */
> +#define SWPS2_LCTL_NOACK (0x0 << 18)
> +#define SWPS2_LCTL_TXDTOEN (0x1 << 8)
> +#define SWPS2_LCTL_STOPERREN (0x1 << 3)
> +#define SWPS2_LCTL_ACKERREN (0x1 << 2)
> +#define SWPS2_LCTL_PARERREN (0x1 << 1)
> +#define SWPS2_LCTL_RXDTOEN (0x1 << 0)
> +
> +/* SW_PS2_FSTAT */
> +#define SWPS2_FSTA_RXRDY (1 << 0)
> +#define SWPS2_FSTA_RXOF (1 << 1)
> +#define SWPS2_FSTA_RXUF (1 << 2)
> +#define SWPS2_FSTA_TXRDY (1 << 8)
> +#define SWPS2_FSTA_TXOF (1 << 9)
> +#define SWPS2_FSTA_TXUF (1 << 10)
> +
> +#define SW_PS2_SAMPLE_CLK (1000000)
> +#define SW_PS2_SCLK (125000)
> +
> +struct sunxips2data {
> + int irq;
> + spinlock_t ps2_lock;
> + void __iomem *base_address; /* virt address of control registers*/
> + struct serio *serio; /* serio*/
> + struct device *dev;
> + struct clk *pclk;
> +};
> +
> +/*********************/
> +/* Interrupt handler */
> +/*********************/
> +static irqreturn_t sunxips2_interrupt(int irq, void *dev_id)
> +{
> + struct sunxips2data *drvdata = dev_id;
> + u32 intr_status;
> + u32 fifo_status;
> + unsigned char byte;
> + u32 rval;
> + u32 error = 0;
> +
> + spin_lock(&drvdata->ps2_lock);
> +
> + /* Get the PS/2 interrupts and clear them */
> + intr_status = readl(drvdata->base_address + SW_PS2_LSTAT);
> + fifo_status = readl(drvdata->base_address + SW_PS2_FSTAT);
> +
> + /*Check Line Status Register*/
> + if (intr_status & 0x10f) {
> + if (intr_status & 0x08)
> + dev_info(drvdata->dev, "PS/2 Stop Bit Error!");
> + if (intr_status & 0x04)
> + dev_info(drvdata->dev, "PS/2 Acknowledge Error!\n");
> + if (intr_status & 0x02)
> + dev_info(drvdata->dev, "PS/2 Parity Error!\n");
> + if (intr_status & 0x100)
> + dev_info(drvdata->dev, "PS/2 Transmit Data Timeout!\n");
> + if (intr_status & 0x01)
> + dev_info(drvdata->dev, "PS/2 Receive Data Timeout!\n");
> +
> + writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4, drvdata->base_address + SW_PS2_GCTRL);/*reset PS/2 controller*/
> + writel(0x10f, drvdata->base_address + SW_PS2_LSTAT);
> +
> + error = 1;
> + }
> +
> + /*Check FIFO Status Register*/
> + if (fifo_status & 0x0606) {
> + if (fifo_status & 0x400)
> + dev_info(drvdata->dev, "PS/2 Tx FIFO Underflow!\n");
> + if (fifo_status & 0x200)
> + dev_info(drvdata->dev, "PS/2 Tx FIFO Overflow!\n");
> + if (fifo_status & 0x04)
> + dev_info(drvdata->dev, "PS/2 Rx FIFO Underflow!\n");
> + if (fifo_status & 0x02)
> + dev_info(drvdata->dev, "PS/2 Rx FIFO Overflow!\n");
> +
> + writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4, drvdata->base_address + SW_PS2_GCTRL); /*reset PS/2 controller*/
> + writel(0x707, drvdata->base_address + SW_PS2_FSTAT);
> + error = 1;
> + }
> +
> + rval = (fifo_status >> 16) & 0x3;
> + while (!error && rval--) {
> + byte = readl(drvdata->base_address + SW_PS2_DATA) & 0xff;
> + dev_info(drvdata->dev, "PS/2 Receive %02x\n", byte);
You really want to log every input byte in the logs?
> + serio_interrupt(drvdata->serio, byte, 0);
> + }
> +
> + writel(intr_status, drvdata->base_address + SW_PS2_LSTAT);
> + writel(fifo_status, drvdata->base_address + SW_PS2_FSTAT);
> +
> + spin_unlock(&drvdata->ps2_lock);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int sunxips2_open(struct serio *pserio)
> +{
> + struct sunxips2data *drvdata = pserio->port_data;
> + u32 src_clk = 0;
> + u32 clk_scdf;
> + u32 clk_pcdf;
> + u32 rval;
> +
> + /*Set Line Control And Enable Interrupt*/
> + rval = SWPS2_LCTL_TXDTOEN|SWPS2_LCTL_STOPERREN|SWPS2_LCTL_ACKERREN|SWPS2_LCTL_PARERREN|SWPS2_LCTL_RXDTOEN;
> + writel(rval, drvdata->base_address + SW_PS2_LCTRL);
> +
> + /*Reset FIFO*/
> + writel(0x3<<16 | 0x607, drvdata->base_address + SW_PS2_FCTRL);
> +
> + src_clk = clk_get_rate(drvdata->pclk);
> +
> + if (!src_clk) {
> + dev_info(drvdata->dev, "w_ps2c_set_sclk error, source clock is 0.");
> + return -1;
> + }
> +
> + /*Set Clock Divider Register*/
> + clk_scdf = ((src_clk + (SW_PS2_SAMPLE_CLK>>1)) / SW_PS2_SAMPLE_CLK - 1);
> + clk_pcdf = ((SW_PS2_SAMPLE_CLK + (SW_PS2_SCLK>>1)) / SW_PS2_SCLK - 1);
> + rval = (clk_scdf<<8) | clk_pcdf;/* | (PS2_DEBUG_SEL<<16);*/
> + writel(rval, drvdata->base_address + SW_PS2_CLKDR);
> +
> + /*Set Global Control Register*/
> + rval = SWPS2_RESET|SWPS2_INTEN|SWPS2_MASTER|SWPS2_BUSEN;
> + writel(rval, drvdata->base_address + SW_PS2_GCTRL);
> +
> + udelay(100);
> +
> + return 0;
> +}
> +
> +static void sunxips2_close(struct serio *pserio)
> +{
> + struct sunxips2data *drvdata = pserio->port_data;
> +
> + spin_lock(&drvdata->ps2_lock);
> + /* Disable the PS2 interrupts */
> + writel(0, drvdata->base_address + SW_PS2_GCTRL);
> + spin_unlock(&drvdata->ps2_lock);
> +}
> +
> +static int sunxips2_write(struct serio *pserio, unsigned char val)
> +{
> + struct sunxips2data *drvdata = (struct sunxips2data *)pserio->port_data;
> + u32 timeout = 10000;
> +
> + do {
> + if (readl(drvdata->base_address + SW_PS2_FSTAT) & SWPS2_FSTA_TXRDY) {
> + writel(val, drvdata->base_address + SW_PS2_DATA);
> + return 0;
> + }
> + } while (timeout--);
> +
> + return -1;
> +}
> +
> +static int sunxips2_probe(struct platform_device *ofdev)
> +{
> + struct resource *res; /* IO mem resources */
> + struct sunxips2data *drvdata;
> + struct serio *serio;
> + struct device *dev = &ofdev->dev;
> + unsigned int irq;
> + int error;
> +
> + drvdata = devm_kzalloc(dev, sizeof(struct sunxips2data), GFP_KERNEL);
> + serio = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
serio is a refcounted structure, it should not be allocated with devm.
> + if (!drvdata || !serio)
> + error = -ENOMEM;
and...?
> +
> + /* Request clock */
> + drvdata->pclk = clk_get(dev, NULL);
> + if (IS_ERR(drvdata->pclk))
> + dev_dbg(dev, "couldn't get clock %li\n",
> + PTR_ERR(drvdata->pclk));
Why %li?
> +
> + if (!IS_ERR(drvdata->pclk)) {
"} else {"
> + error = clk_prepare_enable(drvdata->pclk);
> + if (error < 0) {
> + dev_err(dev, "failed to enable clock %d\n", error);
> + return error;
Leaking clk here.
> + }
> + }
> +
> + /* IO */
> + res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> + drvdata->base_address = devm_ioremap_resource(dev, res);
> + if (IS_ERR(drvdata->base_address)) {
> + dev_err(dev, "failed to map registers\n");
> + error = PTR_ERR(drvdata->base_address);
aaaand...?
> + }
> +
> + serio->id.type = SERIO_8042;
> + serio->write = sunxips2_write;
> + serio->open = sunxips2_open;
> + serio->close = sunxips2_close;
> + serio->port_data = drvdata;
> + serio->dev.parent = dev;
> + strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
> + strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
> +
> + platform_set_drvdata(ofdev, drvdata);
> + serio_register_port(serio);
> +
> + /* Get IRQ for the device */
> + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
> + if (!irq) {
> + dev_err(dev, "no IRQ found\n");
> + return -ENODEV;
Leaking clk and serio here.
> + }
> +
> + drvdata->irq = irq;
> + drvdata->serio = serio;
> + drvdata->dev = dev;
> + error = devm_request_any_context_irq(drvdata->dev, drvdata->irq, &sunxips2_interrupt, 0,
> + DRIVER_NAME, drvdata);
Please try to fit in 80 columns.
> + if (error) {
> + dev_err(drvdata->dev,
> + "Couldn't allocate interrupt %d : error: %d\n", drvdata->irq, error);
> + return error;
> + }
> + return 0; /* success */
> +}
> +
> +static int sunxips2_remove(struct platform_device *of_dev)
> +{
> + struct sunxips2data *drvdata = platform_get_drvdata(of_dev);
> +
> + if (!IS_ERR(drvdata->pclk)) {
> + clk_disable_unprepare(drvdata->pclk);
> + clk_put(drvdata->pclk);
If serio write comes here what will happen?
> + }
> + serio_unregister_port(drvdata->serio);
If interrupt comes here what will happen?
> + mdelay(2);
Why do you need mdelay?
> + return 0;
> +}
> +
> +/* Match table for of_platform binding */
> +static const struct of_device_id sunxips2_of_match[] = {
> + { .compatible = "allwinner,sun7i-a20-ps2", },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(of, sunxips2_of_match);
> +
> +/*platform driver structure*/
> +static struct platform_driver sunxips2_of_driver = {
> + .probe = sunxips2_probe,
> + .remove = sunxips2_remove,
> + .driver = {
> + .name = DRIVER_NAME,
> + .owner = THIS_MODULE,
> + .of_match_table = sunxips2_of_match,
> + },
> +};
> +module_platform_driver(sunxips2_of_driver);
> +
> +MODULE_AUTHOR("Aaron.maoye<leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org, "
Space before "<", closing ">" are missing.
> + "Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
> +MODULE_DESCRIPTION("Sunxi PS/2 driver");
> +MODULE_LICENSE("GPL");
> --
> 1.7.9.5
>
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] input/speaker: additional clicks and tones for future accessibility
From: Vojtech Pavlik @ 2014-12-03 22:57 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Karl Dahlke, linux-input
In-Reply-To: <20141203195811.GB16951@dtor-ws>
On Wed, Dec 03, 2014 at 11:58:11AM -0800, Dmitry Torokhov wrote:
> Hi Karl,
>
> On Tue, Dec 02, 2014 at 12:17:40AM -0500, Karl Dahlke wrote:
> > From: Karl Dahlke <eklhad@gmail.com>
> >
> > Add clicks, tones, and tone sequences to the pc speaker.
> >
> > The speaker driver can play a tone at a specified frequency,
> > or the standard control G bell,
> > which is a special case of TONE at 1000 hz 0.1 seconds.
> > Add kd_mkpulse() to generate a soft click.
> > This is introduced to support accessibility modules and adapters in the future.
> > It is a means to an end.
> > With this function in place, a module can easily provide soft clicks,
> > i.e. audible feedback, whenever a key is depressed,
> > or when that keystroke is echoed on screen.
> > This allows a blind user, for example, to have rapid feedback while typing,
> > even if he is, at the same time, listening to text that is already on screen.
> > It is faster and more convenient than having characters echoed verbally.
> > And it works all the time, even if speech or braille is not working
> > for whatever reason.
> >
> > Also add the function kd_mknotes,
> > which plays a series of tones in the background.
> > Of course this can already be done with kd_mksound and timers,
> > but why should everyone reinvent the wheel?
> > It is better to write the function once, properly, in the kernel,
> > and let modules use it thereafter.
> > Again, this is a means to an end.
> > Accessibility modules can generate rapid sequences of notes
> > to indicate various conditions, sometimes error conditions,
> > especially if speech or braille is not working.
> > These notes may be the only feedback the user has to diagnose the problem.
> > This may be useful to other developers in other situations as well.
> >
> > Finally add kd_mksteps to run something like a chromatic scale,
> > from one frequency to another in specified steps.
> > The half-tone scale, with a step of 6%, starting at middle C, is approximately
> > kd_mksteps(260, 530, 6, 150);
>
> I have exactly the same response as a year earlier:
>
> "I do not think it is a good idea to add SND_PULSE as it can be easily
> implemented by SND_TONE with the additional benefit that parameters of
> the click can be adjusted. Also, if clicking is done elsewhere, it would
> work with other speaker drivers besides pcspkr.
SND_PULSE would make sense in case (and only in case) there are devices
that can emit that kind of sound without being able to implement
SND_TONE.
This is the reason why SND_CLICK and SND_BELL exist.
And, by the way, the implementation of SND_PULSE in the patch is quite
horrible. If a variable-width pulse makes sense at all (based on the
speaker dynamics, a long enough pause will be two clicks and high power
consumption inbetween), it should be done by programming the i8253 to do
a one-shot timer rather than bitbanging it.
> [re kd_mknotes] Can it be put into a library instead? Especially given
> David's work on trying to push the VT code out of the kernel. Also, what
> if you want clicks to go through sound card and not the speaker
> interface?"
>
> In other words, I'd rather have it all be done in userpsace by a daemon
> that listens to all keystrokes and emits notes or clicks or something
> else via whatever sound device is present on the system, be it a PC
> speaker, SPARC speaker, a sound card, or maybe something else.
>
> Thanks.
>
> --
> Dmitry
>
--
Vojtech Pavlik
Director SUSE Labs
^ permalink raw reply
* Re: [BUG] [PATCH] next: cyapa: fix inop touchpad after resume on Acer C720
From: Dmitry Torokhov @ 2014-12-03 23:42 UTC (permalink / raw)
To: Dudley Du; +Cc: 'Jeremiah Mahler', linux-input@vger.kernel.org
In-Reply-To: <9d446cdf85214727b1cd02d7e1537e2b@BN1PR06MB070.namprd06.prod.outlook.com>
Dudley,
On Fri, Nov 28, 2014 at 01:49:15AM +0000, Dudley Du wrote:
> Dmitry,
>
> Yes, I remebered the discussion, and I said it was working.
> At that time, I though it was the suggestion to my patches, so I merged the solution to my pathces,
> and verified on my pathces. But did not run test on the patch you attached.
> Sorry for the misunderstood and the troubles to you. :)
Sorry I was not clear in my request. Anyway, I just applied the patch
(with a minor edit) and pushed it out. It shoudl make it's way into next
today or tomorrow.
Thanks.
>
> Regards,
> Dudley
>
> > -----Original Message-----
> > From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> > Sent: 2014年11月28日 2:16
> > To: Dudley Du; 'Jeremiah Mahler'
> > Cc: linux-kernel@vger.kernel.org; Dudley Du
> > Subject: RE: [BUG] [PATCH] next: cyapa: fix inop touchpad after resume on Acer
> > C720
> >
> > On November 26, 2014 9:45:49 PM PST, Dudley Du <dudley.dulixin@gmail.com>
> > wrote:
> > >Jeremiah,
> > >
> > >I didn't make the special patch for the linux-next before, so I don't
> > >know why
> > >this patch is there and have issue.
> >
> > That was the patch we've discussed some times back and you mentioned it was
> > working for you so I applied it to next.
> >
> > I'll make sure to apply the fixup promptly.
> >
> > >Based on current code in the linux-next, I made below patch to fix this
> > >issue.
> > >Could you please try again with attached patch fix.
> > >
> > >Thanks,
> > >Dudley
> > >
> > >> -----Original Message-----
> > >> From: Jeremiah Mahler [mailto:jmmahler@gmail.com]
> > >> Sent: 2014?11?27? 4:03
> > >> To: Dudley Du
> > >> Cc: linux-kernel@vger.kernel.org
> > >> Subject: Re: [BUG] [PATCH] next: cyapa: fix inop touchpad after
> > >resume on Acer
> > >> C720
> > >>
> > >> Dudley,
> > >>
> > >> On Wed, Nov 26, 2014 at 06:16:00AM +0000, Dudley Du wrote:
> > >> > More info: I did all testings based on kernel 3.14.0 on Acer C70.
> > >> >
> > >>
> > >> I am testing with linux-next 3.18-rc6 on an Acer C720.
> > >>
> > >> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/
> > >>
> > >> > Thanks,
> > >> > Dudley
> > >> >
> > >> []
> > >>
> > >> --
> > >> - Jeremiah Mahler
> > >
> > >From bb717b1c1525ef6b889f0ef735d920eed9e76e72 Mon Sep 17 00:00:00 2001
> > >From: Dudley Du <dudley.dulixin@gmail.com>
> > >Date: Thu, 27 Nov 2014 13:35:09 +0800
> > >Subject: [PATCH] input: cyapa: fix irq error issue in cyapa_resume
> > >To: dmitry.torokhov@gmail.com,
> > > jmmahler@gmail.com
> > >Cc: bleung@google.com,
> > > linux-input@vger.kernel.org
> > >
> > >This patch is aimed to fix the irq error happened on cyapa_resume when
> > >doing suspend/resume testing.
> > >The root cause of this issue is that the cyapa->irq has been removed
> > >but
> > >still used in the driver.
> > >
> > >Signed-off-by: Dudley Du <dudley.dulixin@gmail.com>
> > >---
> > > drivers/input/mouse/cyapa.c | 6 +++---
> > > 1 file changed, 3 insertions(+), 3 deletions(-)
> > >
> > >diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c
> > >index c84a9eb..caaba7b 100644
> > >--- a/drivers/input/mouse/cyapa.c
> > >+++ b/drivers/input/mouse/cyapa.c
> > >@@ -938,7 +938,7 @@ static int __maybe_unused cyapa_suspend(struct
> > >device *dev)
> > > power_mode, error);
> > >
> > > if (device_may_wakeup(dev))
> > >-cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0);
> > >+cyapa->irq_wake = (enable_irq_wake(cyapa->client->irq) == 0);
> > >
> > > mutex_unlock(&input->mutex);
> > >
> > >@@ -956,7 +956,7 @@ static int __maybe_unused cyapa_resume(struct
> > >device *dev)
> > > mutex_lock(&input->mutex);
> > >
> > > if (device_may_wakeup(dev) && cyapa->irq_wake)
> > >-disable_irq_wake(cyapa->irq);
> > >+disable_irq_wake(cyapa->client->irq);
> > >
> > > power_mode = input->users ? PWR_MODE_FULL_ACTIVE : PWR_MODE_OFF;
> > > error = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
> > >@@ -964,7 +964,7 @@ static int __maybe_unused cyapa_resume(struct
> > >device *dev)
> > > dev_warn(dev, "resume: set power mode to %d failed: %d\n",
> > > power_mode, error);
> > >
> > >-enable_irq(cyapa->irq);
> > >+enable_irq(cyapa->client->irq);
> > >
> > > mutex_unlock(&input->mutex);
> > >
> >
> > Hi Dudley,
> > Thanks.
> >
> > --
> > Dmitry
>
> This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v4 1/2] Input: add regulator haptic driver
From: Jaewon Kim @ 2014-12-04 1:43 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Kukjin Kim, linux-kernel, linux-samsung-soc, linux-input,
Hyunhee Kim
In-Reply-To: <547EADAD.9060100@samsung.com>
Hi Dmity,
2014년 12월 03일 15:29에 Jaewon Kim 이(가) 쓴 글:
> Hi Dmitry,
>
> 2014년 12월 03일 15:02에 Dmitry Torokhov 이(가) 쓴 글:
>> Hi Jaewon,
>>
>> On Mon, Dec 01, 2014 at 11:11:12AM +0900, Jaewon Kim wrote:
>>> This patch adds support for haptic driver controlled by
>>> voltage of regulator. And this driver support for
>>> Force Feedback interface from input framework
>>>
>>> Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
>>> Signed-off-by: Hyunhee Kim <hyunhee.kim@samsung.com>
>>> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>>> Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
>>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>>> Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
>>> ---
>>> .../devicetree/bindings/input/regulator-haptic.txt | 21 ++
>>> drivers/input/misc/Kconfig | 11 +
>>> drivers/input/misc/Makefile | 1 +
>>> drivers/input/misc/regulator-haptic.c | 247
>>> ++++++++++++++++++++
>>> include/linux/input/regulator-haptic.h | 31 +++
>>> 5 files changed, 311 insertions(+)
>>> create mode 100644
>>> Documentation/devicetree/bindings/input/regulator-haptic.txt
>>> create mode 100644 drivers/input/misc/regulator-haptic.c
>>> create mode 100644 include/linux/input/regulator-haptic.h
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/input/regulator-haptic.txt
>>> b/Documentation/devicetree/bindings/input/regulator-haptic.txt
>>> new file mode 100644
>>> index 0000000..3ed1c7e
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/input/regulator-haptic.txt
>>> @@ -0,0 +1,21 @@
>>> +* Regulator Haptic Device Tree Bindings
>>> +
>>> +Required Properties:
>>> + - compatible : Should be "regulator-haptic"
>>> + - haptic-supply : Power supply to the haptic motor.
>>> + [*] refer
>>> Documentation/devicetree/bindings/regulator/regulator.txt
>>> +
>>> + - max-microvolt : The maximum voltage value supplied to the haptic
>>> motor.
>>> + [The unit of the voltage is a micro]
>>> +
>>> + - min-microvolt : The minimum voltage value supplied to the haptic
>>> motor.
>>> + [The unit of the voltage is a micro]
>>> +
>>> +Example:
>>> +
>>> + haptics {
>>> + compatible = "regulator-haptic";
>>> + haptic-supply = <&motor_regulator>;
>>> + max-microvolt = <2700000>;
>>> + min-microvolt = <1100000>;
>>> + };
>>> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
>>> index 23297ab..e5e556d 100644
>>> --- a/drivers/input/misc/Kconfig
>>> +++ b/drivers/input/misc/Kconfig
>>> @@ -394,6 +394,17 @@ config INPUT_CM109
>>> To compile this driver as a module, choose M here: the
>>> module will be
>>> called cm109.
>>> +config INPUT_REGULATOR_HAPTIC
>>> + tristate "regulator haptics support"
>>> + select INPUT_FF_MEMLESS
>>> + help
>>> + This option enables device driver support for the haptic
>>> controlled
>>> + by regulator. This driver supports ff-memless interface
>>> + from input framework.
>>> +
>>> + To compile this driver as a module, choose M here: the
>>> + module will be called regulator-haptic.
>>> +
>>> config INPUT_RETU_PWRBUTTON
>>> tristate "Retu Power button Driver"
>>> depends on MFD_RETU
>>> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
>>> index 19c7603..1f135af 100644
>>> --- a/drivers/input/misc/Makefile
>>> +++ b/drivers/input/misc/Makefile
>>> @@ -53,6 +53,7 @@ obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY) +=
>>> pmic8xxx-pwrkey.o
>>> obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
>>> obj-$(CONFIG_INPUT_PWM_BEEPER) += pwm-beeper.o
>>> obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o
>>> +obj-$(CONFIG_INPUT_REGULATOR_HAPTIC) += regulator-haptic.o
>>> obj-$(CONFIG_INPUT_RETU_PWRBUTTON) += retu-pwrbutton.o
>>> obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o
>>> obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
>>> diff --git a/drivers/input/misc/regulator-haptic.c
>>> b/drivers/input/misc/regulator-haptic.c
>>> new file mode 100644
>>> index 0000000..6bc8e45
>>> --- /dev/null
>>> +++ b/drivers/input/misc/regulator-haptic.c
>>> @@ -0,0 +1,247 @@
>>> +/*
>>> + * Regulator haptic driver
>>> + *
>>> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
>>> + * Author: Jaewon Kim <jaewon02.kim@samsung.com>
>>> + * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#include <linux/input.h>
>>> +#include <linux/input/regulator-haptic.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regulator/consumer.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#define MAX_MAGNITUDE_SHIFT 16
>>> +
>>> +struct regulator_haptic {
>>> + struct device *dev;
>>> + struct input_dev *input_dev;
>>> + struct regulator *regulator;
>>> + struct work_struct work;
>>> +
>>> + bool enabled;
>>> + bool suspend_state;
>>> + unsigned int max_volt;
>>> + unsigned int min_volt;
>>> + unsigned int intensity;
>>> + unsigned int magnitude;
>>> +};
>>> +
>>> +static void regulator_haptic_enable(struct regulator_haptic
>>> *haptic, bool state)
>>> +{
>>> + int error;
>>> +
>>> + if (haptic->enabled == state)
>>> + return;
>>> +
>>> + if (state)
>>> + error = regulator_enable(haptic->regulator);
>>> + else
>>> + error = regulator_disable(haptic->regulator);
>>> + if (error) {
>>> + dev_err(haptic->dev, "cannot enable regulator\n");
>>> + return;
>>> + }
>>> +
>>> + haptic->enabled = state;
>>> +}
>>> +
>>> +static void regulator_haptic_work(struct work_struct *work)
>>> +{
>>> + struct regulator_haptic *haptic = container_of(work,
>>> + struct regulator_haptic, work);
>>> + int error;
>>> +
>>> + error = regulator_set_voltage(haptic->regulator,
>>> + haptic->intensity + haptic->min_volt, haptic->max_volt);
>>> + if (error) {
>>> + dev_err(haptic->dev, "cannot set regulator voltage\n");
>>> + return;
>>> + }
>>> +
>>> + if (haptic->magnitude)
>>> + regulator_haptic_enable(haptic, true);
>>> + else
>>> + regulator_haptic_enable(haptic, false);
>>> +}
>>> +
>>> +static int regulator_haptic_play_effect(struct input_dev *input,
>>> void *data,
>>> + struct ff_effect *effect)
>>> +{
>>> + struct regulator_haptic *haptic = input_get_drvdata(input);
>>> + u64 volt_mag_multi;
>>> +
>>> + haptic->magnitude = effect->u.rumble.strong_magnitude;
>>> + if (!haptic->magnitude)
>>> + haptic->magnitude = effect->u.rumble.weak_magnitude;
>>> +
>>> +
>>> + volt_mag_multi = (u64)(haptic->max_volt - haptic->min_volt) *
>>> + haptic->magnitude;
>>> + haptic->intensity = (unsigned int)(volt_mag_multi >>
>>> + MAX_MAGNITUDE_SHIFT);
>>> +
>>> + schedule_work(&haptic->work);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void regulator_haptic_close(struct input_dev *input)
>>> +{
>>> + struct regulator_haptic *haptic = input_get_drvdata(input);
>>> +
>>> + cancel_work_sync(&haptic->work);
>>> + regulator_haptic_enable(haptic, false);
>>> +}
>>> +
>>> +#ifdef CONFIG_OF
>>> +static int regulator_haptic_parse_dt(struct regulator_haptic *haptic)
>>> +{
>>> + struct device_node *node = haptic->dev->of_node;
>>> + int error;
>>> +
>>> + error = of_property_read_u32(node, "max-microvolt",
>>> &haptic->max_volt);
>>> + if (error) {
>>> + dev_err(haptic->dev, "cannot parse max-microvolt\n");
>>> + return error;
>>> + }
>>> +
>>> + error = of_property_read_u32(node, "min-microvolt",
>>> &haptic->min_volt);
>>> + if (error) {
>>> + dev_err(haptic->dev, "cannot parse min-microvolt\n");
>>> + return error;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +#else
>>> +static int regulator_haptic_parse_dt(struct regulator_haptic *haptic)
>>> +{
>>> + return 0;
>>> +}
>>> +#endif /* CONFIG_OF */
>>> +
>>> +static int regulator_haptic_probe(struct platform_device *pdev)
>>> +{
>>> + struct regulator_haptic *haptic;
>>> + struct regulator_haptic_data *data;
>>> + struct input_dev *input_dev;
>>> + int error;
>>> +
>>> + haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
>>> + if (!haptic)
>>> + return -ENOMEM;
>>> +
>>> + haptic->dev = &pdev->dev;
>>> + haptic->enabled = false;
>>> + haptic->suspend_state = false;
>>> + INIT_WORK(&haptic->work, regulator_haptic_work);
>>> +
>>> + if (pdev->dev.of_node) {
>>> + error = regulator_haptic_parse_dt(haptic);
>>> + if (error) {
>>> + dev_err(&pdev->dev, "failed to parse device tree\n");
>>> + return error;
>>> + }
>>> + } else {
>>> + data = dev_get_platdata(&pdev->dev);
>>> + if (data) {
>>> + dev_err(&pdev->dev, "failed to get platdata\n");
>>> + return -EINVAL;
>>> + }
>>> +
>>> + haptic->regulator = data->regulator;
>>> + haptic->max_volt = data->max_volt;
>>> + haptic->min_volt = data->min_volt;
>> Please give preference to platform data if supplied, and if not then try
>> fetching settings from device tree.
>
> Ok. i will give prefrence to platform data in next version.
>
>>
>>> + }
>>> +
>>> + haptic->regulator = devm_regulator_get_exclusive(&pdev->dev,
>>> "haptic");
>>> + if (IS_ERR(haptic->regulator)) {
>>> + dev_err(&pdev->dev, "failed to get regulator\n");
>>> + return PTR_ERR(haptic->regulator);
>>> + }
>>> +
>>> + input_dev = devm_input_allocate_device(&pdev->dev);
>>> + if (!input_dev)
>>> + return -ENOMEM;
>>> +
>>> + haptic->input_dev = input_dev;
>>> + haptic->input_dev->name = "regulator-haptic";
>>> + haptic->input_dev->dev.parent = &pdev->dev;
>>> + haptic->input_dev->close = regulator_haptic_close;
>>> + input_set_drvdata(haptic->input_dev, haptic);
>>> + input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);
>>> +
>>> + error = input_ff_create_memless(input_dev, NULL,
>>> + regulator_haptic_play_effect);
>>> + if (error) {
>>> + dev_err(&pdev->dev, "failed to create force-feedback\n");
>>> + return error;
>>> + }
>>> +
>>> + error = input_register_device(haptic->input_dev);
>>> + if (error) {
>>> + dev_err(&pdev->dev, "failed to register input device\n");
>>> + return error;
>>> + }
>>> +
>>> + platform_set_drvdata(pdev, haptic);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int __maybe_unused regulator_haptic_suspend(struct device *dev)
>>> +{
>>> + struct platform_device *pdev = to_platform_device(dev);
>>> + struct regulator_haptic *haptic = platform_get_drvdata(pdev);
>>> +
>>> + if (haptic->enabled) {
>> You need to protect this code from racing with the work item.
I saw this review now but i sent v5. It did not reflect in v5.
I will send soon and modifies in v6.
>>
>>> + regulator_haptic_enable(haptic, false);
>>> + haptic->suspend_state = true;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int __maybe_unused regulator_haptic_resume(struct device *dev)
>>> +{
>>> + struct platform_device *pdev = to_platform_device(dev);
>>> + struct regulator_haptic *haptic = platform_get_drvdata(pdev);
>>> +
>>> + if (haptic->suspend_state) {
>>> + regulator_haptic_enable(haptic, true);
>>> + haptic->suspend_state = false;
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static SIMPLE_DEV_PM_OPS(regulator_haptic_pm_ops,
>>> + regulator_haptic_suspend, regulator_haptic_resume);
>>> +
>>> +static struct of_device_id regulator_haptic_dt_match[] = {
>>> + { .compatible = "regulator-haptic" },
>>> + { /* sentinel */ },
>>> +};
>>> +
>>> +static struct platform_driver regulator_haptic_driver = {
>>> + .probe = regulator_haptic_probe,
>>> + .driver = {
>>> + .name = "regulator-haptic",
>>> + .of_match_table = regulator_haptic_dt_match,
>>> + .pm = ®ulator_haptic_pm_ops,
>>> + },
>>> +};
>>> +module_platform_driver(regulator_haptic_driver);
>>> +
>>> +MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
>>> +MODULE_AUTHOR("Hyunhee Kim <hyunhee.kim@samsung.com>");
>>> +MODULE_DESCRIPTION("Regulator haptic driver");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/include/linux/input/regulator-haptic.h
>>> b/include/linux/input/regulator-haptic.h
>>> new file mode 100644
>>> index 0000000..05ae038
>>> --- /dev/null
>>> +++ b/include/linux/input/regulator-haptic.h
>>> @@ -0,0 +1,31 @@
>>> +/*
>>> + * Regulator Haptic Platform Data
>>> + *
>>> + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
>>> + * Author: Jaewon Kim <jaewon02.kim@samsung.com>
>>> + * Author: Hyunhee Kim <hyunhee.kim@samsung.com>
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#ifndef _REGULATOR_HAPTIC_H
>>> +#define _REGULATOR_HAPTIC_H
>>> +
>>> +/*
>>> + * struct regulator_haptic_data - Platform device data
>>> + *
>>> + * @regulator: Power supply to the haptic motor
>>> + * @max_volt: maximum voltage value supplied to the haptic motor.
>>> + * <The unit of the voltage is a micro>
>>> + * @min_volt: minimum voltage value supplied to the haptic motor.
>>> + * <The unit of the voltage is a micro>
>>> + */
>>> +struct regulator_haptic_data {
>>> + struct regulator *regulator;
>>> + unsigned int max_volt;
>>> + unsigned int min_volt;
>>> +};
>>> +
>>> +#endif /* _REGULATOR_HAPTIC_H */
>>> --
>>> 1.7.9.5
>>>
>> Thanks.
>>
>
> Thanks.
> Jaewon Kim.
^ permalink raw reply
* [PATCH] input/speaker: additional clicks and tones for future...
From: Karl Dahlke @ 2014-12-04 2:00 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: vojtech, linux-input
In-Reply-To: <20141203225229.GE16951@dtor-ws>
It seems to be the general consensus that these sound functions
should not be integrated into the kernel - and that's ok.
Allow me then to ask one more question if I may.
I have a module, ttyclicks.ko, that makes sounds and clicks and such,
and is used primarily by adapters.
By design, it operates the pc speaker, and is never intended
to vector through a sound card or other such.
In fact it provides feedback when the sound card is not working.
That might eliminate some of your concerns.
My question is, would it be possible to add this module to the kernel tree?
If you wanted to add it under staging, that would be fine.
After all, the Speakup modules are all under staging,
and since so few people use them, that's not a problem.
My modules would also be used by a slim minority,
but that minority would sure find it convenient to have the modules
distributed with the kernel.
If you think this is at least a possibility, I will put a patch together.
If not, I will maintain them privately, as I already do.
To clarify how the module works,
here is the file that would be added as
Documentation/accessibility/ttyclicks.txt
Thank you for your consideration.
======================================================================
The tty clicks module
---------------------
Karl Dahlke
eklhad@gmail.com
When this module is installed, soft clicks accompany
the nonspace characters that are sent to the console,
while a longer swoop indicates a newline character.
These sounds simulate an old fashion teletype running at 2400 baud.
Why would you want such a thing?
You probably wouldn't, but a blind person might.
He can tell, by clicks alone, when the computer responds to a command,
and he can discern the quantity and format of that response,
without any speech or braille.
In addition, the output is throttled, and does not fly by the screen
in a flash, faster than one could possibly hit control S.
This module is separate from any sound cards, thus providing valuable audio
feedback if the sound card is not working.
It can be loaded very early in the boot sequence,
since it does not depend on anything else.
This module uses the in-built toggle speaker at port 0x61.
Not all machines have this speaker, but most do.
If the speaker is lacking, the module is a no-op.
This module will not click and chirp if you are in X.
It responds to text characters that pass through the standard tty,
and will not do anything in graphics mode.
Even the terminal emulator, running under a desktop, still runs through X,
and won't work with ttyclicks.
Switch to a text console to hear the clicks.
Module parameters:
As always, you can run modinfo ttyclicks.ko to review these parameters.
enabled = 1 or 0
If 1, then sounds are enabled as soon as the module is loaded.
If 0, then sounds are not enabled.
These sounds can be turned on or off at run time by the exported symbol
bool ttyclicks_on;
Thus other modules can turn sounds on or off.
In particular, any adapter that includes a lodable module
has access to this master switch.
fgtty = 1 or 0
This parameter enables the clicks that accompany the display of characters
from the foreground tty.
The corresponding exported symbol is
bool ttyclicks_tty;
kmsg = 1 or 0
Printk messages do not pass through the tty,
and do not generate the aforementioned clicks.
However, if this switch is enabled,
each printk message generates a distinctive sequence of tones.
This is like an alarm,
telling the user that he needs to read the message on the screen.
The corresponding exported symbol is
bool ttyclicks_kmsg;
cursormotion = 0 or 1
Many screen programs generate ansi escape sequences that position the cursor
and set character attributes such as underline etc.
This is not true output, and does not generate clicks by default.
However, you can set this parameter to 1 if you want these characters
to generate clicks.
Exported functions.
These are all subject to the master switch ttyclicks_on.
void ttyclicks_click(void);
Generate a 0.6 millisecond pulse.
void ttyclicks_cr(void);
Generate a quick frequency swoop from 2900 to 3600 hz.
This sound is associated with the newline character at the console,
but you can use this function to generate the same sound whenever you wish.
void ttyclicks_notes(const short *notelist);
Play a series of notes in the background.
Each note is defined by two shorts, a frequency and a duration.
The frequency is in hurtz, and the duration is in hundredths of a second.
A frequency of -1 is a rest.
A frequency of 0 terminates the array.
The queue can only hold 64 notes, so don't try to play an entire sonata.
void ttyclicks_steps(int freq1, int freq2, int step, int duration)
Play a series of notes, of the specified duration, moving from
frequency freq1 to frequency freq2 in a geometric progression of step%.
This is a customizable chromatic scale.
The traditional scale, based on half tones, and starting at middle C,
has an approximate step of 6%, and looks like this.
ttyclicks_mksteps(260, 530, 6, 150);
Use a negative step for a descending scale.
void ttyclicks_bell(void);
This function generates an 1800 hz tone for a tenth of a second.
this is associated with the control G bell.
The traditional bell is 1000 hz, but I wanted a slightly higher tone.
As long as this module is loaded, it swallows control G, and sounds the bell,
rather then passing it through to the console and letting the console
ring the bell. This allows the master switch, ttyclicks_on,
to enable or disable the control G bell along with all the other sounds.
You can turn off all the sounds in one go, if they are bothering your roommate.
This module is integral to many command line adapters,
as a complement to speech or braille. Beyond this,
it can prove invaluable if the adapter is not working for any reason.
^ permalink raw reply
* Re: [PATCH 2/3] drivers:input:ps2 Added sunxi A20 ps2 driver, changed makefile and Kconfig
From: Vishnu Patekar @ 2014-12-04 3:08 UTC (permalink / raw)
To: linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Cc: maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org,
msalter-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
jdelvare-l3A5Bk7waGM@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20141203232334.GG16951@dtor-ws>
[-- Attachment #1: Type: text/plain, Size: 14852 bytes --]
Hello Dmitry,
Thank you for comments.
I'll implement these comments and resend it for review.
On Thursday, December 4, 2014, Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> On Thu, Dec 04, 2014 at 04:23:44AM +0530, vishnupatekar wrote:
> > ---
> > drivers/input/serio/Kconfig | 9 ++
> > drivers/input/serio/Makefile | 1 +
> > drivers/input/serio/sunxi-ps2.c | 305
> +++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 315 insertions(+)
> > create mode 100644 drivers/input/serio/sunxi-ps2.c
> >
> > diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
> > index bc2d474..1a86e41 100644
> > --- a/drivers/input/serio/Kconfig
> > +++ b/drivers/input/serio/Kconfig
> > @@ -281,4 +281,13 @@ config HYPERV_KEYBOARD
> > To compile this driver as a module, choose M here: the module
> will
> > be called hyperv_keyboard.
> >
> > +config SERIO_SUNXI_PS2
> > + tristate "Allwinner Sun7i-A20 PS/2 controller"
> > + default m
>
> Why default m? Default should be n. Also it seems it has to depend on
> OF. And what about depending on <arch> || COMPILE_TEST?
>
> > + help
> > + Say Y here if you have Sun7i-A20 Allwinner PS/2 ports.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called sunxi-ps2.
> > +
> > endif
> > diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile
> > index 815d874..0fa0f78 100644
> > --- a/drivers/input/serio/Makefile
> > +++ b/drivers/input/serio/Makefile
> > @@ -29,3 +29,4 @@ obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o
> > obj-$(CONFIG_SERIO_APBPS2) += apbps2.o
> > obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o
> > obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o
> > +obj-$(CONFIG_SERIO_SUNXI_PS2) += sunxi-ps2.o
> > diff --git a/drivers/input/serio/sunxi-ps2.c
> b/drivers/input/serio/sunxi-ps2.c
> > new file mode 100644
> > index 0000000..ccd7b29
> > --- /dev/null
> > +++ b/drivers/input/serio/sunxi-ps2.c
> > @@ -0,0 +1,305 @@
> > +/*
> > + * sunxi-ps2.c Support for Allwinner A20 PS2 host controller
>
> No file names in sources please.
>
> > + *
> > + * Author: Aaron.maoye <leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org <javascript:;>>
> > + * Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org <javascript:;>>
> > + * Based on sunxi-ps2.c 3.0 kernel
> > + *
> > +*/
> > +
> > +#include <linux/module.h>
> > +#include <linux/serio.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/errno.h>
> > +#include <linux/slab.h>
> > +#include <linux/list.h>
> > +#include <linux/io.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/clk.h>
> > +#include <linux/delay.h>
> > +
> > +#define DRIVER_NAME "sunxi-ps2"
> > +
> > +#define RESSIZE(res) (((res)->end - (res)->start)+1)
>
> I am sure we have something generic for it, no?
>
> > +
> > +#define SW_PS2_GCTRL (0x00)
> > +#define SW_PS2_DATA (0x04)
> > +#define SW_PS2_LCTRL (0x08)
> > +#define SW_PS2_LSTAT (0x0c)
> > +#define SW_PS2_FCTRL (0x10)
> > +#define SW_PS2_FSTAT (0x14)
> > +#define SW_PS2_CLKDR (0x18)
> > +
> > +/* SW_PS2_GCTRL */
> > +#define SWPS2_BUSEN (1 << 0)
> > +#define SWPS2_MASTER (1 << 1)
> > +#define SWPS2_RESET (1 << 2)
> > +#define SWPS2_INTEN (1 << 3)
> > +#define SWPS2_INTFLAG (1 << 3)
> > +
> > +/* SW_PS2_LCTRL */
> > +#define SWPS2_LCTL_NOACK (0x0 << 18)
> > +#define SWPS2_LCTL_TXDTOEN (0x1 << 8)
> > +#define SWPS2_LCTL_STOPERREN (0x1 << 3)
> > +#define SWPS2_LCTL_ACKERREN (0x1 << 2)
> > +#define SWPS2_LCTL_PARERREN (0x1 << 1)
> > +#define SWPS2_LCTL_RXDTOEN (0x1 << 0)
> > +
> > +/* SW_PS2_FSTAT */
> > +#define SWPS2_FSTA_RXRDY (1 << 0)
> > +#define SWPS2_FSTA_RXOF (1 << 1)
> > +#define SWPS2_FSTA_RXUF (1 << 2)
> > +#define SWPS2_FSTA_TXRDY (1 << 8)
> > +#define SWPS2_FSTA_TXOF (1 << 9)
> > +#define SWPS2_FSTA_TXUF (1 << 10)
> > +
> > +#define SW_PS2_SAMPLE_CLK (1000000)
> > +#define SW_PS2_SCLK (125000)
> > +
> > +struct sunxips2data {
> > + int irq;
> > + spinlock_t ps2_lock;
> > + void __iomem *base_address; /* virt address of control
> registers*/
> > + struct serio *serio; /* serio*/
> > + struct device *dev;
> > + struct clk *pclk;
> > +};
> > +
> > +/*********************/
> > +/* Interrupt handler */
> > +/*********************/
> > +static irqreturn_t sunxips2_interrupt(int irq, void *dev_id)
> > +{
> > + struct sunxips2data *drvdata = dev_id;
> > + u32 intr_status;
> > + u32 fifo_status;
> > + unsigned char byte;
> > + u32 rval;
> > + u32 error = 0;
> > +
> > + spin_lock(&drvdata->ps2_lock);
> > +
> > + /* Get the PS/2 interrupts and clear them */
> > + intr_status = readl(drvdata->base_address + SW_PS2_LSTAT);
> > + fifo_status = readl(drvdata->base_address + SW_PS2_FSTAT);
> > +
> > + /*Check Line Status Register*/
> > + if (intr_status & 0x10f) {
> > + if (intr_status & 0x08)
> > + dev_info(drvdata->dev, "PS/2 Stop Bit Error!");
> > + if (intr_status & 0x04)
> > + dev_info(drvdata->dev, "PS/2 Acknowledge
> Error!\n");
> > + if (intr_status & 0x02)
> > + dev_info(drvdata->dev, "PS/2 Parity Error!\n");
> > + if (intr_status & 0x100)
> > + dev_info(drvdata->dev, "PS/2 Transmit Data
> Timeout!\n");
> > + if (intr_status & 0x01)
> > + dev_info(drvdata->dev, "PS/2 Receive Data
> Timeout!\n");
> > +
> > + writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4,
> drvdata->base_address + SW_PS2_GCTRL);/*reset PS/2 controller*/
> > + writel(0x10f, drvdata->base_address + SW_PS2_LSTAT);
> > +
> > + error = 1;
> > + }
> > +
> > + /*Check FIFO Status Register*/
> > + if (fifo_status & 0x0606) {
> > + if (fifo_status & 0x400)
> > + dev_info(drvdata->dev, "PS/2 Tx FIFO
> Underflow!\n");
> > + if (fifo_status & 0x200)
> > + dev_info(drvdata->dev, "PS/2 Tx FIFO Overflow!\n");
> > + if (fifo_status & 0x04)
> > + dev_info(drvdata->dev, "PS/2 Rx FIFO
> Underflow!\n");
> > + if (fifo_status & 0x02)
> > + dev_info(drvdata->dev, "PS/2 Rx FIFO Overflow!\n");
> > +
> > + writel(readl(drvdata->base_address + SW_PS2_GCTRL)|0x4,
> drvdata->base_address + SW_PS2_GCTRL); /*reset PS/2 controller*/
> > + writel(0x707, drvdata->base_address + SW_PS2_FSTAT);
> > + error = 1;
> > + }
> > +
> > + rval = (fifo_status >> 16) & 0x3;
> > + while (!error && rval--) {
> > + byte = readl(drvdata->base_address + SW_PS2_DATA) & 0xff;
> > + dev_info(drvdata->dev, "PS/2 Receive %02x\n", byte);
>
> You really want to log every input byte in the logs?
>
> > + serio_interrupt(drvdata->serio, byte, 0);
> > + }
> > +
> > + writel(intr_status, drvdata->base_address + SW_PS2_LSTAT);
> > + writel(fifo_status, drvdata->base_address + SW_PS2_FSTAT);
> > +
> > + spin_unlock(&drvdata->ps2_lock);
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int sunxips2_open(struct serio *pserio)
> > +{
> > + struct sunxips2data *drvdata = pserio->port_data;
> > + u32 src_clk = 0;
> > + u32 clk_scdf;
> > + u32 clk_pcdf;
> > + u32 rval;
> > +
> > + /*Set Line Control And Enable Interrupt*/
> > + rval =
> SWPS2_LCTL_TXDTOEN|SWPS2_LCTL_STOPERREN|SWPS2_LCTL_ACKERREN|SWPS2_LCTL_PARERREN|SWPS2_LCTL_RXDTOEN;
> > + writel(rval, drvdata->base_address + SW_PS2_LCTRL);
> > +
> > + /*Reset FIFO*/
> > + writel(0x3<<16 | 0x607, drvdata->base_address + SW_PS2_FCTRL);
> > +
> > + src_clk = clk_get_rate(drvdata->pclk);
> > +
> > + if (!src_clk) {
> > + dev_info(drvdata->dev, "w_ps2c_set_sclk error, source
> clock is 0.");
> > + return -1;
> > + }
> > +
> > + /*Set Clock Divider Register*/
> > + clk_scdf = ((src_clk + (SW_PS2_SAMPLE_CLK>>1)) / SW_PS2_SAMPLE_CLK
> - 1);
> > + clk_pcdf = ((SW_PS2_SAMPLE_CLK + (SW_PS2_SCLK>>1)) / SW_PS2_SCLK -
> 1);
> > + rval = (clk_scdf<<8) | clk_pcdf;/* | (PS2_DEBUG_SEL<<16);*/
> > + writel(rval, drvdata->base_address + SW_PS2_CLKDR);
> > +
> > + /*Set Global Control Register*/
> > + rval = SWPS2_RESET|SWPS2_INTEN|SWPS2_MASTER|SWPS2_BUSEN;
> > + writel(rval, drvdata->base_address + SW_PS2_GCTRL);
> > +
> > + udelay(100);
> > +
> > + return 0;
> > +}
> > +
> > +static void sunxips2_close(struct serio *pserio)
> > +{
> > + struct sunxips2data *drvdata = pserio->port_data;
> > +
> > + spin_lock(&drvdata->ps2_lock);
> > + /* Disable the PS2 interrupts */
> > + writel(0, drvdata->base_address + SW_PS2_GCTRL);
> > + spin_unlock(&drvdata->ps2_lock);
> > +}
> > +
> > +static int sunxips2_write(struct serio *pserio, unsigned char val)
> > +{
> > + struct sunxips2data *drvdata = (struct sunxips2data
> *)pserio->port_data;
> > + u32 timeout = 10000;
> > +
> > + do {
> > + if (readl(drvdata->base_address + SW_PS2_FSTAT) &
> SWPS2_FSTA_TXRDY) {
> > + writel(val, drvdata->base_address + SW_PS2_DATA);
> > + return 0;
> > + }
> > + } while (timeout--);
> > +
> > + return -1;
> > +}
> > +
> > +static int sunxips2_probe(struct platform_device *ofdev)
> > +{
> > + struct resource *res; /* IO mem resources */
> > + struct sunxips2data *drvdata;
> > + struct serio *serio;
> > + struct device *dev = &ofdev->dev;
> > + unsigned int irq;
> > + int error;
> > +
> > + drvdata = devm_kzalloc(dev, sizeof(struct sunxips2data),
> GFP_KERNEL);
> > + serio = devm_kzalloc(dev, sizeof(struct serio), GFP_KERNEL);
>
> serio is a refcounted structure, it should not be allocated with devm.
>
> > + if (!drvdata || !serio)
> > + error = -ENOMEM;
>
> and...?
>
> > +
> > + /* Request clock */
> > + drvdata->pclk = clk_get(dev, NULL);
> > + if (IS_ERR(drvdata->pclk))
> > + dev_dbg(dev, "couldn't get clock %li\n",
> > + PTR_ERR(drvdata->pclk));
>
> Why %li?
>
> > +
> > + if (!IS_ERR(drvdata->pclk)) {
>
> "} else {"
>
>
> > + error = clk_prepare_enable(drvdata->pclk);
> > + if (error < 0) {
> > + dev_err(dev, "failed to enable clock %d\n", error);
> > + return error;
>
> Leaking clk here.
>
> > + }
> > + }
> > +
> > + /* IO */
> > + res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
> > + drvdata->base_address = devm_ioremap_resource(dev, res);
> > + if (IS_ERR(drvdata->base_address)) {
> > + dev_err(dev, "failed to map registers\n");
> > + error = PTR_ERR(drvdata->base_address);
>
> aaaand...?
>
> > + }
> > +
> > + serio->id.type = SERIO_8042;
> > + serio->write = sunxips2_write;
> > + serio->open = sunxips2_open;
> > + serio->close = sunxips2_close;
> > + serio->port_data = drvdata;
> > + serio->dev.parent = dev;
> > + strlcpy(serio->name, dev_name(dev), sizeof(serio->name));
> > + strlcpy(serio->phys, dev_name(dev), sizeof(serio->phys));
> > +
> > + platform_set_drvdata(ofdev, drvdata);
> > + serio_register_port(serio);
> > +
> > + /* Get IRQ for the device */
> > + irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
> > + if (!irq) {
> > + dev_err(dev, "no IRQ found\n");
> > + return -ENODEV;
>
> Leaking clk and serio here.
>
> > + }
> > +
> > + drvdata->irq = irq;
> > + drvdata->serio = serio;
> > + drvdata->dev = dev;
> > + error = devm_request_any_context_irq(drvdata->dev, drvdata->irq,
> &sunxips2_interrupt, 0,
> > + DRIVER_NAME, drvdata);
>
> Please try to fit in 80 columns.
>
> > + if (error) {
> > + dev_err(drvdata->dev,
> > + "Couldn't allocate interrupt %d : error: %d\n",
> drvdata->irq, error);
> > + return error;
> > + }
> > + return 0; /* success */
> > +}
> > +
> > +static int sunxips2_remove(struct platform_device *of_dev)
> > +{
> > + struct sunxips2data *drvdata = platform_get_drvdata(of_dev);
> > +
> > + if (!IS_ERR(drvdata->pclk)) {
> > + clk_disable_unprepare(drvdata->pclk);
> > + clk_put(drvdata->pclk);
>
> If serio write comes here what will happen?
>
> > + }
> > + serio_unregister_port(drvdata->serio);
>
> If interrupt comes here what will happen?
>
> > + mdelay(2);
>
> Why do you need mdelay?
>
> > + return 0;
> > +}
> > +
> > +/* Match table for of_platform binding */
> > +static const struct of_device_id sunxips2_of_match[] = {
> > + { .compatible = "allwinner,sun7i-a20-ps2", },
> > + { },
> > +};
> > +
> > +MODULE_DEVICE_TABLE(of, sunxips2_of_match);
> > +
> > +/*platform driver structure*/
> > +static struct platform_driver sunxips2_of_driver = {
> > + .probe = sunxips2_probe,
> > + .remove = sunxips2_remove,
> > + .driver = {
> > + .name = DRIVER_NAME,
> > + .owner = THIS_MODULE,
> > + .of_match_table = sunxips2_of_match,
> > + },
> > +};
> > +module_platform_driver(sunxips2_of_driver);
> > +
> > +MODULE_AUTHOR("Aaron.maoye<leafy.myeh-Q9AEpCAkrSgqDJ6do+/SaQ@public.gmane.org <javascript:;>, "
>
> Space before "<", closing ">" are missing.
>
> > + "Vishnu Patekar <vishnupatekar0510-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
> <javascript:;>>");
> > +MODULE_DESCRIPTION("Sunxi PS/2 driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 1.7.9.5
> >
>
> Thanks.
>
> --
> Dmitry
>
> --
> You received this message because you are subscribed to the Google Groups
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org <javascript:;>.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: Type: text/html, Size: 19954 bytes --]
^ permalink raw reply
* Re: [PATCH] Input: Initialize device count variables by -1
From: Aniroop Mathur @ 2014-12-04 4:22 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org, a.mathur
In-Reply-To: <20141203223521.GD16951@dtor-ws>
On Thu, Dec 4, 2014 at 4:05 AM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Thu, Dec 04, 2014 at 02:09:06AM +0530, Aniroop Mathur wrote:
>> This patch initializes input device count variables by -1 in order
>> to avoid extra subtraction operation performed everytime for
>> allocation of an input device.
>>
>> Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
>
> Applied, thank you.
>
Thank you Mr. Torokhov for applying the patch !!
And umm... Could you please provide a link where I can see it ?
Actually I tried to search on kernel.org but could not find it.
Regards,
Aniroop
>> ---
>> drivers/input/gameport/gameport.c | 4 ++--
>> drivers/input/joystick/xpad.c | 4 ++--
>> drivers/input/misc/ims-pcu.c | 4 ++--
>> drivers/input/serio/serio.c | 4 ++--
>> drivers/input/serio/serio_raw.c | 4 ++--
>> 5 files changed, 10 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
>> index 24c41ba..d8371e8 100644
>> --- a/drivers/input/gameport/gameport.c
>> +++ b/drivers/input/gameport/gameport.c
>> @@ -490,14 +490,14 @@ EXPORT_SYMBOL(gameport_set_phys);
>> */
>> static void gameport_init_port(struct gameport *gameport)
>> {
>> - static atomic_t gameport_no = ATOMIC_INIT(0);
>> + static atomic_t gameport_no = ATOMIC_INIT(-1);
>>
>> __module_get(THIS_MODULE);
>>
>> mutex_init(&gameport->drv_mutex);
>> device_initialize(&gameport->dev);
>> dev_set_name(&gameport->dev, "gameport%lu",
>> - (unsigned long)atomic_inc_return(&gameport_no) - 1);
>> + (unsigned long)atomic_inc_return(&gameport_no));
>> gameport->dev.bus = &gameport_bus;
>> gameport->dev.release = gameport_release_port;
>> if (gameport->parent)
>> diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
>> index 177602c..64dc7cb 100644
>> --- a/drivers/input/joystick/xpad.c
>> +++ b/drivers/input/joystick/xpad.c
>> @@ -850,7 +850,7 @@ static void xpad_led_set(struct led_classdev *led_cdev,
>>
>> static int xpad_led_probe(struct usb_xpad *xpad)
>> {
>> - static atomic_t led_seq = ATOMIC_INIT(0);
>> + static atomic_t led_seq = ATOMIC_INIT(-1);
>> long led_no;
>> struct xpad_led *led;
>> struct led_classdev *led_cdev;
>> @@ -863,7 +863,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
>> if (!led)
>> return -ENOMEM;
>>
>> - led_no = (long)atomic_inc_return(&led_seq) - 1;
>> + led_no = (long)atomic_inc_return(&led_seq);
>>
>> snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
>> led->xpad = xpad;
>> diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
>> index 719410f..69caee9 100644
>> --- a/drivers/input/misc/ims-pcu.c
>> +++ b/drivers/input/misc/ims-pcu.c
>> @@ -1851,7 +1851,7 @@ static int ims_pcu_identify_type(struct ims_pcu *pcu, u8 *device_id)
>>
>> static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
>> {
>> - static atomic_t device_no = ATOMIC_INIT(0);
>> + static atomic_t device_no = ATOMIC_INIT(-1);
>>
>> const struct ims_pcu_device_info *info;
>> int error;
>> @@ -1882,7 +1882,7 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
>> }
>>
>> /* Device appears to be operable, complete initialization */
>> - pcu->device_no = atomic_inc_return(&device_no) - 1;
>> + pcu->device_no = atomic_inc_return(&device_no);
>>
>> /*
>> * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor
>> diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
>> index b29134d..21698cc 100644
>> --- a/drivers/input/serio/serio.c
>> +++ b/drivers/input/serio/serio.c
>> @@ -514,7 +514,7 @@ static void serio_release_port(struct device *dev)
>> */
>> static void serio_init_port(struct serio *serio)
>> {
>> - static atomic_t serio_no = ATOMIC_INIT(0);
>> + static atomic_t serio_no = ATOMIC_INIT(-1);
>>
>> __module_get(THIS_MODULE);
>>
>> @@ -525,7 +525,7 @@ static void serio_init_port(struct serio *serio)
>> mutex_init(&serio->drv_mutex);
>> device_initialize(&serio->dev);
>> dev_set_name(&serio->dev, "serio%ld",
>> - (long)atomic_inc_return(&serio_no) - 1);
>> + (long)atomic_inc_return(&serio_no));
>> serio->dev.bus = &serio_bus;
>> serio->dev.release = serio_release_port;
>> serio->dev.groups = serio_device_attr_groups;
>> diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
>> index c9a02fe..71ef5d6 100644
>> --- a/drivers/input/serio/serio_raw.c
>> +++ b/drivers/input/serio/serio_raw.c
>> @@ -292,7 +292,7 @@ static irqreturn_t serio_raw_interrupt(struct serio *serio, unsigned char data,
>>
>> static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
>> {
>> - static atomic_t serio_raw_no = ATOMIC_INIT(0);
>> + static atomic_t serio_raw_no = ATOMIC_INIT(-1);
>> struct serio_raw *serio_raw;
>> int err;
>>
>> @@ -303,7 +303,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv)
>> }
>>
>> snprintf(serio_raw->name, sizeof(serio_raw->name),
>> - "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no) - 1);
>> + "serio_raw%ld", (long)atomic_inc_return(&serio_raw_no));
>> kref_init(&serio_raw->kref);
>> INIT_LIST_HEAD(&serio_raw->client_list);
>> init_waitqueue_head(&serio_raw->wait);
>> --
>> 1.9.1
>>
>
> --
> Dmitry
^ permalink raw reply
* Re: [PATCH] input / PM: Replace CONFIG_PM_RUNTIME with CONFIG_PM
From: Ferruh Yigit @ 2014-12-04 7:58 UTC (permalink / raw)
To: Rafael J. Wysocki, Dmitry Torokhov
Cc: linux-input@vger.kernel.org, Jingoo Han, Paul Gortmaker,
Linux Kernel Mailing List, Linux PM list
In-Reply-To: <8119438.MdkFLx3Wvh@vostro.rjw.lan>
On 12/03/2014 03:47 AM, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> After commit b2b49ccbdd54 (PM: Kconfig: Set PM_RUNTIME if PM_SLEEP is
> selected) PM_RUNTIME is always set if PM is set, so #ifdef blocks
> depending on CONFIG_PM_RUNTIME may now be changed to depend on
> CONFIG_PM.
>
> The alternative of CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME may be
> replaced with CONFIG_PM too.
>
> Make these changes in 2 files under drivers/input/.
>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ferruh Yigit <fery@cypress.com>
> ---
>
> Note: This depends on commit b2b49ccbdd54 (PM: Kconfig: Set PM_RUNTIME if
> PM_SLEEP is selected) which is only in linux-next at the moment (via the
> linux-pm tree).
>
> Please let me know if it is OK to take this one into linux-pm.
>
> ---
> drivers/input/keyboard/samsung-keypad.c | 2 +-
> drivers/input/touchscreen/cyttsp4_core.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> Index: linux-pm/drivers/input/keyboard/samsung-keypad.c
> ===================================================================
> --- linux-pm.orig/drivers/input/keyboard/samsung-keypad.c
> +++ linux-pm/drivers/input/keyboard/samsung-keypad.c
> @@ -463,7 +463,7 @@ static int samsung_keypad_remove(struct
> return 0;
> }
>
> -#ifdef CONFIG_PM_RUNTIME
> +#ifdef CONFIG_PM
> static int samsung_keypad_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> Index: linux-pm/drivers/input/touchscreen/cyttsp4_core.c
> ===================================================================
> --- linux-pm.orig/drivers/input/touchscreen/cyttsp4_core.c
> +++ linux-pm/drivers/input/touchscreen/cyttsp4_core.c
> @@ -1716,7 +1716,7 @@ static void cyttsp4_free_si_ptrs(struct
> kfree(si->btn_rec_data);
> }
>
> -#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)
> +#ifdef CONFIG_PM
> static int cyttsp4_core_sleep(struct cyttsp4 *cd)
> {
> int rc;
>
>
--
regards,
ferruh
This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.
^ permalink raw reply
* Re: [PATCH v2 2/2] Input: amikbd - Allocate temporary keymap buffer on the stack
From: Geert Uytterhoeven @ 2014-12-04 9:00 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input@vger.kernel.org, Linux/m68k
In-Reply-To: <20141203225934.GF16951@dtor-ws>
Hi Dmitry,
On Wed, Dec 3, 2014 at 11:59 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Sun, Nov 30, 2014 at 10:30:20AM +0100, Geert Uytterhoeven wrote:
>> Allocate the temporary buffer needed for initialization of the console
>> keyboard maps (512 bytes, as NR_KEYS = 256) on the stack instead of
>> statically, to reduce kernel size.
>>
>> add/remove: 0/1 grow/shrink: 0/0 up/down: 0/-512 (-512)
>> function old new delta
>> temp_map 512 - -512
>
> So because it is marked __initdata and is placed into a separate
> section we have to allocate the space in the image?
Indeed. __initdata consumes space in both the vmlinux image and in
memory.
Note that we don't have __initbss for uninitialized data, which would
obviously still consume space in memory.
> Anyway, applied both, thank you.
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v12 02/19] input: cyapa: add device resource management infrastructure support
From: Dmitry Torokhov @ 2014-12-04 17:43 UTC (permalink / raw)
To: Dudley Du; +Cc: rydberg, bleung, linux-input, linux-kernel
In-Reply-To: <1417599025-21681-3-git-send-email-dudley.dulixin@gmail.com>
On Wed, Dec 03, 2014 at 05:30:08PM +0800, Dudley Du wrote:
> Remove cyapa_remove() method, add cyapa_open() and cyapa_close() methods for
> input interface, also modified together with driver's memory and IRQ resource
> allocations to support device resource management infrastructure to reduce
> the mistakes of resource management.
> TEST=test on Chromebooks.
>
> Signed-off-by: Dudley Du <dudley.dulixin@gmail.com>
OK, so this patch (in slightly modified form) has already been applied,
so you can drop it from the next respin.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read firmware image function support
From: Dmitry Torokhov @ 2014-12-04 17:46 UTC (permalink / raw)
To: Dudley Du
Cc: Dudley Du, rydberg@euromail.se, bleung@google.com,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <ad3bf85500174b25a4dc8f796d10d0a3@BN1PR06MB070.namprd06.prod.outlook.com>
On Mon, Nov 10, 2014 at 11:05:39AM +0000, Dudley Du wrote:
> Thanks, Dmitry
>
> > -----Original Message-----
> > From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> > Sent: 2014?11?10? 16:40
> > To: Dudley Du
> > Cc: rydberg@euromail.se; Dudley Du; bleung@google.com;
> > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read
> > firmware image function support
> >
> > On Mon, Nov 03, 2014 at 04:33:07PM +0800, Dudley Du wrote:
> > > Add read firmware image function supported for gen3 trackpad device,
> > > it can be used through debugfs read_fw interface.
> >
> > Why do we need this? Can we do the same via usespace program accessing
> > the i2c device through /dev/i2c-N?
>
> This interface is used to test and debug only. It's defined and required by the chromium projects.
>
> And in the driver side, becase the firmware image read process is done based on interrupt signal,
> if do this in userspace through /dev/i2c-N, there will be two issues:
> 1) for gen5, after each command, an interrupt will be asserted, so if throug /dev/i2c-N,
> userspace program cannot get the interrupt signal.
> 2) and when the interrupt signal assert, driver won't know it’s a command signal for image read,
> so it will try to process it as data report.
> To avoid this, additional interface must be added to mark the image read status and
> block interrupt signal to be process as data report.
I believe that while userspace acc4esses the device through /dev/i2c-N
you should unbind the cyapa driver from the device (via sysfs driver
core bind/unbind attribute) so that it doe snot get in the way. Once
diagnostics is done you can bind the driver back to device, restoring
normal operation.
That is how we are planning to handle other devices at factory as
well.
Thanks.
--
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/3] mfd: stmpe: add pull up/down register offsets for STMPE
From: Linus Walleij @ 2014-12-04 18:10 UTC (permalink / raw)
To: Lee Jones, Dmitry Torokhov
Cc: Samuel Ortiz, linux-kernel@vger.kernel.org, Linux Input
In-Reply-To: <20141103122559.GB4538@x1>
On Mon, Nov 3, 2014 at 1:25 PM, Lee Jones <lee.jones@linaro.org> wrote:
> On Fri, 24 Oct 2014, Dmitry Torokhov wrote:
>
>> On Mon, Oct 20, 2014 at 07:46:05AM +0100, Lee Jones wrote:
>> > On Sat, 18 Oct 2014, Linus Walleij wrote:
>> >
>> > > This adds the register offsets for pull up/down for the STMPE
>> > > 1601, 1801 and 24xx expanders. This is used to bias GPIO lines
>> > > and keypad lines.
>> > >
>> > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>> > > ---
>> > > Hi Sam, Lee: I think you should just ACK this so Dmitry can take the
>> > > patch series through the input tree, where the registers need to be
>> > > used to enable the keypad on the STMPE2401.
>> > > ---
>> > > drivers/mfd/stmpe.c | 4 ++++
>> > > drivers/mfd/stmpe.h | 3 +++
>> > > include/linux/mfd/stmpe.h | 2 ++
>> > > 3 files changed, 9 insertions(+)
>> >
>> > Does this need to go in with the other patches in the set?
>> >
>> > I'm _guessing_ that, as you've sent them separately, they can be
>> > applied separately?
>> >
>> > This needs to go in via MFD, but for my own reference:
>> >
>> > Acked-by: Lee Jones <lee.jones@linaro.org>
>>
>> The new register definitions are needed for patch #3. If you insist on
>> this going through MFD then please take the other 2 patches with my Ack
>> through MFD tree as well I do not think we need the whole song and dance
>> trying to synchronize 2 trees.
>
> Actually, I can't see the other patches as they weren't sent to me.
>
> Please apply them all to your tree with my Ack.
Dmitry can you please apply them so we don't miss this merge window...
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 1/3] mfd: stmpe: add pull up/down register offsets for STMPE
From: Dmitry Torokhov @ 2014-12-04 18:23 UTC (permalink / raw)
To: Linus Walleij
Cc: Lee Jones, Samuel Ortiz, linux-kernel@vger.kernel.org,
Linux Input
In-Reply-To: <CACRpkdb45QGkC7aOCMRZ3SH9+effNz1FAGxto6bDR_i7sfZuzw@mail.gmail.com>
On Thu, Dec 04, 2014 at 07:10:30PM +0100, Linus Walleij wrote:
> On Mon, Nov 3, 2014 at 1:25 PM, Lee Jones <lee.jones@linaro.org> wrote:
> > On Fri, 24 Oct 2014, Dmitry Torokhov wrote:
> >
> >> On Mon, Oct 20, 2014 at 07:46:05AM +0100, Lee Jones wrote:
> >> > On Sat, 18 Oct 2014, Linus Walleij wrote:
> >> >
> >> > > This adds the register offsets for pull up/down for the STMPE
> >> > > 1601, 1801 and 24xx expanders. This is used to bias GPIO lines
> >> > > and keypad lines.
> >> > >
> >> > > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> >> > > ---
> >> > > Hi Sam, Lee: I think you should just ACK this so Dmitry can take the
> >> > > patch series through the input tree, where the registers need to be
> >> > > used to enable the keypad on the STMPE2401.
> >> > > ---
> >> > > drivers/mfd/stmpe.c | 4 ++++
> >> > > drivers/mfd/stmpe.h | 3 +++
> >> > > include/linux/mfd/stmpe.h | 2 ++
> >> > > 3 files changed, 9 insertions(+)
> >> >
> >> > Does this need to go in with the other patches in the set?
> >> >
> >> > I'm _guessing_ that, as you've sent them separately, they can be
> >> > applied separately?
> >> >
> >> > This needs to go in via MFD, but for my own reference:
> >> >
> >> > Acked-by: Lee Jones <lee.jones@linaro.org>
> >>
> >> The new register definitions are needed for patch #3. If you insist on
> >> this going through MFD then please take the other 2 patches with my Ack
> >> through MFD tree as well I do not think we need the whole song and dance
> >> trying to synchronize 2 trees.
> >
> > Actually, I can't see the other patches as they weren't sent to me.
> >
> > Please apply them all to your tree with my Ack.
>
> Dmitry can you please apply them so we don't miss this merge window...
I had a question about missing error handling in 3/3? Have you seen it?
--
Dmitry
^ permalink raw reply
* Re: [PATCH] Input: Initialize device count variables by -1
From: Dmitry Torokhov @ 2014-12-04 18:27 UTC (permalink / raw)
To: Aniroop Mathur; +Cc: linux-input@vger.kernel.org, a.mathur
In-Reply-To: <CADYu30_FS0A0=fh-uyQ84m8uNkgfs7Ns2OCnigXAM=i5KrPETA@mail.gmail.com>
On Thu, Dec 04, 2014 at 09:52:26AM +0530, Aniroop Mathur wrote:
> On Thu, Dec 4, 2014 at 4:05 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> > On Thu, Dec 04, 2014 at 02:09:06AM +0530, Aniroop Mathur wrote:
> >> This patch initializes input device count variables by -1 in order
> >> to avoid extra subtraction operation performed everytime for
> >> allocation of an input device.
> >>
> >> Signed-off-by: Aniroop Mathur <aniroop.mathur@gmail.com>
> >
> > Applied, thank you.
> >
>
> Thank you Mr. Torokhov for applying the patch !!
>
> And umm... Could you please provide a link where I can see it ?
> Actually I tried to search on kernel.org but could not find it.
It's in the 'next' branch of my tree on git.kernel.org.
Thanks.
--
Dmitry
^ permalink raw reply
* RE: [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read firmware image function support
From: Dudley Du @ 2014-12-05 1:43 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: rydberg@euromail.se, bleung@google.com,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
David Solda
In-Reply-To: <20141204174641.GB4806@dtor-ws>
> -----Original Message-----
> From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> Sent: 2014年12月5日 1:47
> To: Dudley Du
> Cc: Dudley Du; rydberg@euromail.se; bleung@google.com;
> linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read
> firmware image function support
>
> On Mon, Nov 10, 2014 at 11:05:39AM +0000, Dudley Du wrote:
> > Thanks, Dmitry
> >
> > > -----Original Message-----
> > > From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> > > Sent: 2014?11?10? 16:40
> > > To: Dudley Du
> > > Cc: rydberg@euromail.se; Dudley Du; bleung@google.com;
> > > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > > Subject: Re: [PATCH v9 15/18] input: cyapa: add gen3 trackpad device read
> > > firmware image function support
> > >
> > > On Mon, Nov 03, 2014 at 04:33:07PM +0800, Dudley Du wrote:
> > > > Add read firmware image function supported for gen3 trackpad device,
> > > > it can be used through debugfs read_fw interface.
> > >
> > > Why do we need this? Can we do the same via usespace program accessing
> > > the i2c device through /dev/i2c-N?
> >
> > This interface is used to test and debug only. It's defined and required by the
> chromium projects.
> >
> > And in the driver side, becase the firmware image read process is done based on
> interrupt signal,
> > if do this in userspace through /dev/i2c-N, there will be two issues:
> > 1) for gen5, after each command, an interrupt will be asserted, so if throug
> /dev/i2c-N,
> > userspace program cannot get the interrupt signal.
> > 2) and when the interrupt signal assert, driver won't know it’s a command signal
> for image read,
> > so it will try to process it as data report.
> > To avoid this, additional interface must be added to mark the image read status
> and
> > block interrupt signal to be process as data report.
>
> I believe that while userspace acc4esses the device through /dev/i2c-N
> you should unbind the cyapa driver from the device (via sysfs driver
> core bind/unbind attribute) so that it doe snot get in the way. Once
> diagnostics is done you can bind the driver back to device, restoring
> normal operation.
>
> That is how we are planning to handle other devices at factory as
> well.
Thanks, I will remove the debugfs interfaces from the patach series.
>
> Thanks.
>
> --
> Dmitry
This message and any attachments may contain Cypress (or its subsidiaries) confidential information. If it has been received in error, please advise the sender and immediately delete this message.
^ permalink raw reply
* [PATCH 1/2] HID: wacom - Add support for DTU-1031X
From: Ping Cheng @ 2014-12-05 2:23 UTC (permalink / raw)
To: jkosina; +Cc: linux-input, Ping Cheng
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/hid/wacom_wac.c | 7 +++++++
drivers/hid/wacom_wac.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index a8a19a5..b65e0d7 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1847,6 +1847,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
break;
case DTUS:
+ case DTUSX:
sync = wacom_dtus_irq(wacom_wac);
break;
@@ -2211,6 +2212,7 @@ int wacom_setup_pentouch_input_capabilities(struct input_dev *input_dev,
/* fall through */
case DTUS:
+ case DTUSX:
case PL:
case DTU:
__set_bit(BTN_TOOL_PEN, input_dev->keybit);
@@ -2722,6 +2724,10 @@ static const struct wacom_features wacom_features_0xFB =
{ "Wacom DTU1031", 22096, 13960, 511, 0,
DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
+static const struct wacom_features wacom_features_0x32F =
+ { "Wacom DTU1031X", 22472, 12728, 511, 0,
+ DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
+ WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
static const struct wacom_features wacom_features_0x57 =
{ "Wacom DTK2241", 95640, 54060, 2047, 63,
DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
@@ -3057,6 +3063,7 @@ const struct hid_device_id wacom_ids[] = {
{ USB_DEVICE_WACOM(0x315) },
{ USB_DEVICE_WACOM(0x317) },
{ USB_DEVICE_WACOM(0x323) },
+ { USB_DEVICE_WACOM(0x32F) },
{ USB_DEVICE_WACOM(0x4001) },
{ USB_DEVICE_WACOM(0x4004) },
{ USB_DEVICE_WACOM(0x5000) },
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 128cbb3..5384043 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -80,6 +80,7 @@ enum {
PL,
DTU,
DTUS,
+ DTUSX,
INTUOS,
INTUOS3S,
INTUOS3,
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] HID: wacom - Update maximum X/Y accounding to outbound offset
From: Ping Cheng @ 2014-12-05 2:25 UTC (permalink / raw)
To: jkosina; +Cc: linux-input, Ping Cheng
Defined outbound offset for DTU and Cintiq. But didn't update
the relevant maximum values. Oops...
Signed-off-by: Ping Cheng <pingc@wacom.com>
---
drivers/hid/wacom_wac.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index b65e0d7..7b7a61a 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -2685,11 +2685,11 @@ static const struct wacom_features wacom_features_0x317 =
INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .touch_max = 16,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0xF4 =
- { "Wacom Cintiq 24HD", 104280, 65400, 2047, 63,
+ { "Wacom Cintiq 24HD", 104080, 65200, 2047, 63,
WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0xF8 =
- { "Wacom Cintiq 24HD touch", 104280, 65400, 2047, 63, /* Pen */
+ { "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */
WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
@@ -2707,7 +2707,7 @@ static const struct wacom_features wacom_features_0xC6 =
{ "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,
WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
static const struct wacom_features wacom_features_0x304 =
- { "Wacom Cintiq 13HD", 59352, 33648, 1023, 63,
+ { "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0xC7 =
@@ -2721,7 +2721,7 @@ static const struct wacom_features wacom_features_0xF0 =
{ "Wacom DTU1631", 34623, 19553, 511, 0,
DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xFB =
- { "Wacom DTU1031", 22096, 13960, 511, 0,
+ { "Wacom DTU1031", 21896, 13760, 511, 0,
DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
static const struct wacom_features wacom_features_0x32F =
@@ -2742,15 +2742,15 @@ static const struct wacom_features wacom_features_0x5D = /* Touch */
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0xCC =
- { "Wacom Cintiq 21UX2", 87000, 65400, 2047, 63,
+ { "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63,
WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0xFA =
- { "Wacom Cintiq 22HD", 95640, 54060, 2047, 63,
+ { "Wacom Cintiq 22HD", 95440, 53860, 2047, 63,
WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
static const struct wacom_features wacom_features_0x5B =
- { "Wacom Cintiq 22HDT", 95640, 54060, 2047, 63,
+ { "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63,
WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
@@ -2897,7 +2897,7 @@ static const struct wacom_features wacom_features_0x6004 =
{ "ISD-V4", 12800, 8000, 255, 0,
TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x307 =
- { "Wacom ISDv5 307", 59352, 33648, 2047, 63,
+ { "Wacom ISDv5 307", 59152, 33448, 2047, 63,
CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
@@ -2906,7 +2906,7 @@ static const struct wacom_features wacom_features_0x309 =
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,
.check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
static const struct wacom_features wacom_features_0x30A =
- { "Wacom ISDv5 30A", 59352, 33648, 2047, 63,
+ { "Wacom ISDv5 30A", 59152, 33448, 2047, 63,
CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
.oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox