Disable magnetic screen on/off sensor

michalurban

Senior Member
Jul 11, 2010
772
86
0
Near Prague
Hi,

I believe the title says it all. I tried to find the solution here but without success. While Im satisfied with my Nexus 7 case, I found out that sometimes if I just close it and put the tablet into bag it fails to turn the screen off. So, Id prefer to do that manually.

Is there a software way to disable the magnetic sensor? I dont want to play tailor with my case ... :)
 

ExploreMN

Senior Member
Jun 23, 2007
1,574
463
0
Just manually turn it off. Closing the case won't turn your screen back on...
If the problem is that as the tab shuffles around in your bag and the case cover opens just enough to turn it back on, that's a different issue. Then you'll need some type of band or something to put around it.

Sent from my Nexus 7 using Tapatalk 2
 
Last edited:
  • Like
Reactions: michalurban

mat helm

Member
Jan 7, 2013
17
7
0
Ive been hoping in someone else finding the way to disable it in the code. Anyway, I guess Ill get another case and see ... THX! :good:
Until seeing it on youtube, I wasn't even aware of this feature. The amazing thing to me is the fact that the actual case sold for the N7 at the google store does not have this feature (ie. no magnet)......:confused:
 

khaytsus

Senior Member
Apr 8, 2008
7,263
1,176
243
Central Kentucky
Im afraid I took the matters into my own hands and solved my magnetic problem once and for all ... :laugh:
Your case isn't nearly as attractive now.

Seriously, I can't see how this was a real issue unless your case was designed badly. Example; some flip-around cases if not shielded will turn the N7 off when flipped around.
 

michalurban

Senior Member
Jul 11, 2010
772
86
0
Near Prague
Your case isn't nearly as attractive now.

Seriously, I can't see how this was a real issue unless your case was designed badly. Example; some flip-around cases if not shielded will turn the N7 off when flipped around.
Well, small hole inside the case isnt a big deal for me. Anyway, the problem was that the case managed to turn the tablet off only when closed really good. And if closed, only a few milimeters (say 2) of movement of the front cover to the left made the case wake my N7. I couldnt really be sure what would the Thing :) do in my bag - but the case itself is good, co I kept it this way.
 

gianptune

Senior Member
Oct 10, 2010
212
87
0
This can be done strictly via software. Here is a modified version of the kernel driver from drivers/input/lid.c that allows you to enable/disable this feature. By default, it acts normally. To disable the magnetic switch, do "echo 0 > /sys/module/lid/parameters/lid_enabled", or use any other app you want to write to that file. To enable it again, just write a non-zero value to the parameter. Ive only tested it on my nexus7, but it seems to work perfectly.

Code:
/*
 * ASUS Lid driver.
 */
#include <linux/module.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/gpio_event.h>
#include <asm/gpio.h>
#include <../gpio-names.h>

#include "lid.h"

MODULE_DESCRIPTION(DRIVER_LID);
MODULE_LICENSE("GPL");

/*
 * functions declaration
 */
static void lid_report_function(struct work_struct *dat);
static int lid_input_device_create(void);
static ssize_t show_lid_status(struct device *class, struct device_attribute *attr,char *buf);
/*
 * global variable
 */
static unsigned int hall_sensor_gpio = TEGRA_GPIO_PS6;
static struct workqueue_struct *lid_wq;

static struct input_dev	 *lid_indev;
static struct platform_device *lid_dev; /* Device structure */

// to allow enabling/disabling the lid switch
static int lid_enabled = 1;
module_param( lid_enabled, int, 0644 );


static DEVICE_ATTR(lid_status, S_IWUSR | S_IRUGO, show_lid_status,NULL);

/* Attribute Descriptor */
static struct attribute *lid_attrs[] = {
    &dev_attr_lid_status.attr,
        NULL
};

/* Attribute group */
static struct attribute_group lid_attr_group = {
        .attrs = lid_attrs,
};


static ssize_t show_lid_status(struct device *class,struct device_attribute *attr,char *buf)
{
	return sprintf(buf, "%d\n", gpio_get_value(hall_sensor_gpio));
}

static irqreturn_t lid_interrupt_handler(int irq, void *dev_id){

    if( lid_enabled )
    {
        int gpio = irq_to_gpio(irq);
        if (gpio == hall_sensor_gpio){
            LID_NOTICE("LID interrupt handler...gpio: %d..\n", gpio_get_value(hall_sensor_gpio));
            queue_delayed_work(lid_wq, &lid_hall_sensor_work, 0);
        }
    }
    else
    {
        printk( "lid: ignoring irq\n" );
    }
	return IRQ_HANDLED;
}


static int lid_irq_hall_sensor(void)
{
	int rc = 0 ;
	unsigned gpio = hall_sensor_gpio;
	unsigned irq = gpio_to_irq(hall_sensor_gpio);
	const char* label = "hall_sensor" ;

	LID_INFO("gpio = %d, irq = %d\n", gpio, irq);
	LID_INFO("GPIO = %d , state = %d\n", gpio, gpio_get_value(gpio));

	tegra_gpio_enable(gpio);
	rc = gpio_request(gpio, label);
	if (rc) {
		LID_ERR("gpio_request failed for input %d\n", gpio);
	}

	rc = gpio_direction_input(gpio) ;
	if (rc) {
		LID_ERR("gpio_direction_input failed for input %d\n", gpio);
		goto err_gpio_direction_input_failed;
	}
	LID_INFO("GPIO = %d , state = %d\n", gpio, gpio_get_value(gpio));

	rc = request_irq(irq, lid_interrupt_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, label, lid_indev);
	if (rc < 0) {
		LID_ERR("Could not register for %s interrupt, irq = %d, rc = %d\n", label, irq, rc);
		rc = -EIO;
		goto err_gpio_request_irq_fail ;
	}
	enable_irq_wake(irq);
	LID_INFO("LID irq = %d, rc = %d\n", irq, rc);

	return 0 ;

err_gpio_request_irq_fail :
	gpio_free(gpio);
err_gpio_direction_input_failed:
	return rc;
}

static void lid_report_function(struct work_struct *dat)
{
	int value = 0;

	if (lid_indev == NULL){
		LID_ERR("LID input device doesn't exist\n");
		return;
	}
	msleep(CONVERSION_TIME_MS);
	value = gpio_get_value(hall_sensor_gpio);
	if(value)
		input_report_switch(lid_indev, SW_LID, 0);
	else
		input_report_switch(lid_indev, SW_LID, 1);
	input_sync(lid_indev);
	LID_NOTICE("SW_LID report value = %d\n", value);
}

static int lid_input_device_create(void){
	int err = 0;

	lid_indev = input_allocate_device();
	if (!lid_indev) {
		LID_ERR("lid_indev allocation fails\n");
		err = -ENOMEM;
		goto exit;
	}

	lid_indev->name = "lid_input";
	lid_indev->phys = "/dev/input/lid_indev";

	set_bit(EV_SW, lid_indev->evbit);
	set_bit(SW_LID, lid_indev->swbit);

	err = input_register_device(lid_indev);
	if (err) {
		LID_ERR("lid_indev registration fails\n");
		goto exit_input_free;
	}
	return 0;

exit_input_free:
	input_free_device(lid_indev);
	lid_indev = NULL;
exit:
	return err;

}

static int __init lid_init(void)
{
	int err_code = 0;
	printk(KERN_INFO "%s+ #####\n", __func__);
	LID_NOTICE("start LID init.....\n");

	lid_dev = platform_device_register_simple("LID", -1, NULL, 0);
	if (!lid_dev){
                printk ("LID_init: error\n");
                return -ENOMEM;
        }

	sysfs_create_group((struct kobject*)&lid_dev->dev.kobj, &lid_attr_group);

	err_code = lid_input_device_create();
	if(err_code != 0)
		return err_code;
	lid_wq = create_singlethread_workqueue("lid_wq");
	INIT_DELAYED_WORK_DEFERRABLE(&lid_hall_sensor_work, lid_report_function);

	lid_irq_hall_sensor();

	return 0;
}

static void __exit lid_exit(void)
{
	input_unregister_device(lid_indev);
	sysfs_remove_group(&lid_dev->dev.kobj, &lid_attr_group);
	platform_device_unregister(lid_dev);
}

module_init(lid_init);
module_exit(lid_exit);
 
  • Like
Reactions: dtr145r

jtrosky

Senior Member
May 8, 2008
3,901
1,150
0
So how would one go about implementing this modified code? Personally, I can't believe that there is not a standard setting to enable/disable this feature, but it ROM developers and/or users can implement this modified code easily, that would be a big help!

Thanks.

Sent from my ASUS Transformer Pad TF700T using Tapatalk 2
 

khaytsus

Senior Member
Apr 8, 2008
7,263
1,176
243
Central Kentucky
So how would one go about implementing this modified code? Personally, I can't believe that there is not a standard setting to enable/disable this feature, but it ROM developers and/or users can implement this modified code easily, that would be a big help!

Thanks.
To disable the magnetic switch, do "echo 0 > /sys/module/lid/parameters/lid_enabled"
The code was for reference. EDIT: No it's not, I'm an idiot.
 
Last edited:

rmm200

Senior Member
Apr 15, 2011
1,063
263
0
Bend
Not the way I read it. The modified code has to be built into a kernel to access the option file.

Sent from my Nexus 7 using xda app-developers app
 

gianptune

Senior Member
Oct 10, 2010
212
87
0
Yes, this is one of the files that make up the kernel, with about 10 lines added to it. You would have to replace the file in the kernel source code, build the kernel, insert that kernel into a boot.img, and flash it to your tablet. If you can't manage all that, then you could pester the person who does make the kernel you're using to add it.
 
Last edited:

dtr145r

Senior Member
Nov 11, 2010
1,534
336
0
Pennsylvania
This can be done strictly via software. Here is a modified version of the kernel driver from drivers/input/lid.c that allows you to enable/disable this feature. By default, it acts normally. To disable the magnetic switch, do "echo 0 > /sys/module/lid/parameters/lid_enabled", or use any other app you want to write to that file. To enable it again, just write a non-zero value to the parameter. Ive only tested it on my nexus7, but it seems to work perfectly.

Code:
/*
 * ASUS Lid driver.
 */
#include <linux/module.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include <linux/gpio_event.h>
#include <asm/gpio.h>
#include <../gpio-names.h>

#include "lid.h"

MODULE_DESCRIPTION(DRIVER_LID);
MODULE_LICENSE("GPL");

/*
 * functions declaration
 */
static void lid_report_function(struct work_struct *dat);
static int lid_input_device_create(void);
static ssize_t show_lid_status(struct device *class, struct device_attribute *attr,char *buf);
/*
 * global variable
 */
static unsigned int hall_sensor_gpio = TEGRA_GPIO_PS6;
static struct workqueue_struct *lid_wq;

static struct input_dev	 *lid_indev;
static struct platform_device *lid_dev; /* Device structure */

// to allow enabling/disabling the lid switch
static int lid_enabled = 1;
module_param( lid_enabled, int, 0644 );


static DEVICE_ATTR(lid_status, S_IWUSR | S_IRUGO, show_lid_status,NULL);

/* Attribute Descriptor */
static struct attribute *lid_attrs[] = {
    &dev_attr_lid_status.attr,
        NULL
};

/* Attribute group */
static struct attribute_group lid_attr_group = {
        .attrs = lid_attrs,
};


static ssize_t show_lid_status(struct device *class,struct device_attribute *attr,char *buf)
{
	return sprintf(buf, "%d\n", gpio_get_value(hall_sensor_gpio));
}

static irqreturn_t lid_interrupt_handler(int irq, void *dev_id){

    if( lid_enabled )
    {
        int gpio = irq_to_gpio(irq);
        if (gpio == hall_sensor_gpio){
            LID_NOTICE("LID interrupt handler...gpio: %d..\n", gpio_get_value(hall_sensor_gpio));
            queue_delayed_work(lid_wq, &lid_hall_sensor_work, 0);
        }
    }
    else
    {
        printk( "lid: ignoring irq\n" );
    }
	return IRQ_HANDLED;
}


static int lid_irq_hall_sensor(void)
{
	int rc = 0 ;
	unsigned gpio = hall_sensor_gpio;
	unsigned irq = gpio_to_irq(hall_sensor_gpio);
	const char* label = "hall_sensor" ;

	LID_INFO("gpio = %d, irq = %d\n", gpio, irq);
	LID_INFO("GPIO = %d , state = %d\n", gpio, gpio_get_value(gpio));

	tegra_gpio_enable(gpio);
	rc = gpio_request(gpio, label);
	if (rc) {
		LID_ERR("gpio_request failed for input %d\n", gpio);
	}

	rc = gpio_direction_input(gpio) ;
	if (rc) {
		LID_ERR("gpio_direction_input failed for input %d\n", gpio);
		goto err_gpio_direction_input_failed;
	}
	LID_INFO("GPIO = %d , state = %d\n", gpio, gpio_get_value(gpio));

	rc = request_irq(irq, lid_interrupt_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, label, lid_indev);
	if (rc < 0) {
		LID_ERR("Could not register for %s interrupt, irq = %d, rc = %d\n", label, irq, rc);
		rc = -EIO;
		goto err_gpio_request_irq_fail ;
	}
	enable_irq_wake(irq);
	LID_INFO("LID irq = %d, rc = %d\n", irq, rc);

	return 0 ;

err_gpio_request_irq_fail :
	gpio_free(gpio);
err_gpio_direction_input_failed:
	return rc;
}

static void lid_report_function(struct work_struct *dat)
{
	int value = 0;

	if (lid_indev == NULL){
		LID_ERR("LID input device doesn't exist\n");
		return;
	}
	msleep(CONVERSION_TIME_MS);
	value = gpio_get_value(hall_sensor_gpio);
	if(value)
		input_report_switch(lid_indev, SW_LID, 0);
	else
		input_report_switch(lid_indev, SW_LID, 1);
	input_sync(lid_indev);
	LID_NOTICE("SW_LID report value = %d\n", value);
}

static int lid_input_device_create(void){
	int err = 0;

	lid_indev = input_allocate_device();
	if (!lid_indev) {
		LID_ERR("lid_indev allocation fails\n");
		err = -ENOMEM;
		goto exit;
	}

	lid_indev->name = "lid_input";
	lid_indev->phys = "/dev/input/lid_indev";

	set_bit(EV_SW, lid_indev->evbit);
	set_bit(SW_LID, lid_indev->swbit);

	err = input_register_device(lid_indev);
	if (err) {
		LID_ERR("lid_indev registration fails\n");
		goto exit_input_free;
	}
	return 0;

exit_input_free:
	input_free_device(lid_indev);
	lid_indev = NULL;
exit:
	return err;

}

static int __init lid_init(void)
{
	int err_code = 0;
	printk(KERN_INFO "%s+ #####\n", __func__);
	LID_NOTICE("start LID init.....\n");

	lid_dev = platform_device_register_simple("LID", -1, NULL, 0);
	if (!lid_dev){
                printk ("LID_init: error\n");
                return -ENOMEM;
        }

	sysfs_create_group((struct kobject*)&lid_dev->dev.kobj, &lid_attr_group);

	err_code = lid_input_device_create();
	if(err_code != 0)
		return err_code;
	lid_wq = create_singlethread_workqueue("lid_wq");
	INIT_DELAYED_WORK_DEFERRABLE(&lid_hall_sensor_work, lid_report_function);

	lid_irq_hall_sensor();

	return 0;
}

static void __exit lid_exit(void)
{
	input_unregister_device(lid_indev);
	sysfs_remove_group(&lid_dev->dev.kobj, &lid_attr_group);
	platform_device_unregister(lid_dev);
}

module_init(lid_init);
module_exit(lid_exit);
im interested in trying this on the sprint GS4.
can you possibly be a little more detailed on what i need to do?

thank you very much.
 

Bob Smith42

Senior Member
Jun 7, 2011
761
136
0
In my opinion the best solution to this problem is two steps:

1) Remove any magnet in the case cover. Disables smart cover feature physically rather than software.
2) Use NFC tags with programs configured to control exactly the items needed, e.g. sleep mode, settings, wi-fi, etc.

This may require two to four NFC tags, one for each major scenario. These might be "deep sleep, battery save", "sleep with fast restore", "wake no communicate", "wake and communication", etc. You could put the tags on a strip of material along with color codes. Touch the tag to the NFC sensor and no messing around.

As others may notice, I attended the XDA dev conference. LOL
 

sasa31

Member
Dec 18, 2009
34
4
0
shiraz
As I know all magnetic cases or stuffs are harmful for mobile phones or tablets...
By the way do you guys think that, can this little magnet in the case ، hurm n7 in the long term ?
 

brizey

Senior Member
Aug 6, 2011
2,451
620
0
As I know all magnetic cases or stuffs are harmful for mobile phones or tablets...
By the way do you guys think that, can this little magnet in the case ، hurm n7 in the long term ?
I ordered my N7 during the IO in which it was announced. Been in a magnetic case since then, so about a year and a half. What do you "know" is harmful? A static magnetic field is unlikely to harm solid state electronics or affect their operation.

Sent from my SCH-I545 using Tapatalk