I want to use an Xbox360 game controller on my Galaxy sIII internation (i9300).
It is not working properly : although it is detected by the Android usbHostManager, it is not generating Eventhub ==> the driver does not kicked in. I do have the xpad.c driver.
Here are the setup details :
i9300
xbox360 controller, microsoft : 045e:028e
keylayout file here : Vendor_045e_Product_028e.kl
Input Device Configuration file Vendor_045e_Product_028e.idc NOT here (in any folders listed here : source.android.com/devices/input/input-device-configuration-files.html)
ROM : 13.0-20160519-UNOFFICIAL-temasek-i9300 (compiled myself from darkened_sky advice)
Kernel : 3.0.101-CM-g9001c4e
controller did not work either with my previous ROM, the last official CM for this device.
controller does not work either with a samsung tab active with Samsung's firmware running on it.
controller works perfectly on a moto G, unmodified.
lsusb detects the controller, the led are lit when connected and the logcat does log the UsbHostManager adding the device with the correct vendorID and productID (in decimal, not in hexa).
So... What should I do to have it running correctly through the Android stack ?
here are more relevant data :
Code:
06-03 13:06:32.693 2404 2434 W art : Long monitor contention event with owner method=void com.android.server.am.BroadcastQueue.processNextBroadcast(boolean) from BroadcastQueue.java:649 waiters=0 for 230ms
06-03 13:06:34.353 2404 2537 D UsbHostManager: Added device UsbDevice[mName=/dev/bus/usb/002/002,mVendorId=1118,mProductId=654,mClass=255,mSubclass=255,mProtocol=255,mManufacturerName=©Microsoft Corporation,mProductName=Controller,mVersion=2.0,mSerialNumber=16890DA,mConfigurations=[
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbConfiguration[mId=1,mName=null,mAttributes=160,mMaxPower=250,mInterfaces=[
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=255,mSubclass=93,mProtocol=1,mEndpoints=[
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=32,mInterval=4]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=1,mAttributes=3,mMaxPacketSize=32,mInterval=8]]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=255,mSubclass=93,mProtocol=3,mEndpoints=[
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=130,mAttributes=3,mMaxPacketSize=32,mInterval=2]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=2,mAttributes=3,mMaxPacketSize=32,mInterval=4]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=32,mInterval=64]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=3,mAttributes=3,mMaxPacketSize=32,mInterval=16]]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbInterface[mId=2,mAlternateSetting=0,mName=null,mClass=255,mSubclass=93,mProtocol=2,mEndpoints=[
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbEndpoint[mAddress=132,mAttributes=3,mMaxPacketSize=32,mInterval=16]]
06-03 13:06:34.353 2404 2537 D UsbHostManager: UsbInterface[mId=3,mAlternateSetting=0,mName=Xbox Security Method 3, Version 1.00, © 2005 Microsoft Corporation. All rights reserved.,mClass=255,mSubclass=253,mProtocol=19,mEndpoints=[]]]
06-03 13:06:35.888 2404 3862 D NetlinkSocketObserver: NeighborEvent{elapsedMs=179275, 10.2.64.1, [E48D8C3459BB], RTM_NEWNEIGH, NUD_STALE}
that you can compare to a MOUSE correctly handled :
Code:
06-03 13:54:28.208 6102 6154 D com.facebook.appevents.AppEventsLogger: Got unexpected exception: java.io.EOFException
06-03 13:54:28.663 2421 2469 E EventHub: could not get driver version for /dev/input/mouse0, Not a typewriter
06-03 13:54:28.673 2421 2539 D UsbHostManager: Added device UsbDevice[mName=/dev/bus/usb/002/002,mVendorId=2821,mProductId=6057,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=PixArt,mProductName=Asus USB Optical Mouse,mVersion=1.16,mSerialNumber=null,mConfigurations=[
06-03 13:54:28.673 2421 2539 D UsbHostManager: UsbConfiguration[mId=1,mName=null,mAttributes=160,mMaxPower=50,mInterfaces=[
06-03 13:54:28.673 2421 2539 D UsbHostManager: UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=3,mSubclass=1,mProtocol=2,mEndpoints=[
06-03 13:54:28.673 2421 2539 D UsbHostManager: UsbEndpoint[mAddress=129,mAttributes=3,mMaxPacketSize=4,mInterval=10]]]]
06-03 13:54:28.708 2421 2469 D EventHub: No input device configuration file found for device 'PixArt Asus USB Optical Mouse'.
06-03 13:54:28.708 2421 2469 I EventHub: New device: id=12, fd=229, path='/dev/input/event12', name='PixArt Asus USB Optical Mouse', classes=0x80000008, configuration='', keyLayout='', keyCharacterMap='', builtinKeyboard=false, wakeMechanism=EVIOCSSUSPENDBLOCK, usingClockIoctl=true
06-03 13:54:28.743 2421 2469 I InputReader: Device added: id=12, name='PixArt Asus USB Optical Mouse', sources=0x00002002
lsusb return :
Code:
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0001
Bus 001 Device 002: ID 1519:0020
Bus 002 Device 004: ID 045e:028e
I know about the xboxdrv for linux computer but xoxdrv is running in userspace, thus I have no idea how to port it on android, if possible.
The xpad.c driver for CM has been modified, but these modifications were abandoned : as far as I understood them, I don't think that you should have change the issue. But I will try to compile an image with the xpad.c version. The xpad.c driver : some development and modifications had been done for it but are "abandoned" as status. Differences are mainly to support the xbox One controller but other minors (maybe significant differences) are present.
https://github.com/CyanogenMod/andr...a7a2918913df308/drivers/input/joystick/xpad.c
Mine (the one running for my current phone) can be found here :
android/system/kernel/samsung/smdk4412/drivers/input/joystick
If you need more data to help me, I would be glad to deliver it.
Thank you for any decisive input. Please forward my issue to experimented android tinkerer that you know if you can't help personally, I would appreciated the gesture a lot.
edit
Just to precise, there is the correct reference in my xpad.c file :
Code:
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
Full file to save you time :
Code:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/usb/input.h>
#define DRIVER_AUTHOR "Marko Friedemann <[email protected]>"
#define DRIVER_DESC "X-Box pad driver"
#define XPAD_PKT_LEN 32
/* xbox d-pads should map to buttons, as is required for DDR pads
but we map them to axes when possible to simplify things */
#define MAP_DPAD_TO_BUTTONS (1 << 0)
#define MAP_TRIGGERS_TO_BUTTONS (1 << 1)
#define MAP_STICKS_TO_NULL (1 << 2)
#define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \
MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL)
#define XTYPE_XBOX 0
#define XTYPE_XBOX360 1
#define XTYPE_XBOX360W 2
#define XTYPE_UNKNOWN 3
static int dpad_to_buttons;
module_param(dpad_to_buttons, bool, S_IRUGO);
MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
static int triggers_to_buttons;
module_param(triggers_to_buttons, bool, S_IRUGO);
MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
static int sticks_to_null;
module_param(sticks_to_null, bool, S_IRUGO);
MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
static const struct xpad_device {
u16 idVendor;
u16 idProduct;
char *name;
u8 mapping;
u8 xtype;
} xpad_device[] = {
{ 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX },
{ 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX },
{ 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX },
{ 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX },
{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
{ 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", DANCEPAD_MAP_CONFIG, XTYPE_XBOX },
{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
{ 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 },
{ 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX },
{ 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX },
{ 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX },
{ 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", 0, XTYPE_XBOX },
{ 0x0738, 0x4516, "Mad Catz Control Pad", 0, XTYPE_XBOX },
{ 0x0738, 0x4522, "Mad Catz LumiCON", 0, XTYPE_XBOX },
{ 0x0738, 0x4526, "Mad Catz Control Pad Pro", 0, XTYPE_XBOX },
{ 0x0738, 0x4536, "Mad Catz MicroCON", 0, XTYPE_XBOX },
{ 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX },
{ 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
{ 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX },
{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
{ 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
{ 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", 0, XTYPE_XBOX },
{ 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", 0, XTYPE_XBOX360 },
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
{ 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN }
};
/* buttons shared with xbox and xbox360 */
static const signed short xpad_common_btn[] = {
BTN_A, BTN_B, BTN_X, BTN_Y, /* "analog" buttons */
BTN_START, BTN_SELECT, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
-1 /* terminating entry */
};
/* original xbox controllers only */
static const signed short xpad_btn[] = {
BTN_C, BTN_Z, /* "analog" buttons */
-1 /* terminating entry */
};
/* used when dpad is mapped to buttons */
static const signed short xpad_btn_pad[] = {
BTN_TRIGGER_HAPPY1, BTN_TRIGGER_HAPPY2, /* d-pad left, right */
BTN_TRIGGER_HAPPY3, BTN_TRIGGER_HAPPY4, /* d-pad up, down */
-1 /* terminating entry */
};
/* used when triggers are mapped to buttons */
static const signed short xpad_btn_triggers[] = {
BTN_TL2, BTN_TR2, /* triggers left/right */
-1
};
static const signed short xpad360_btn[] = { /* buttons for x360 controller */
BTN_TL, BTN_TR, /* Button LB/RB */
BTN_MODE, /* The big X button */
-1
};
static const signed short xpad_abs[] = {
ABS_X, ABS_Y, /* left stick */
ABS_RX, ABS_RY, /* right stick */
-1 /* terminating entry */
};
/* used when dpad is mapped to axes */
static const signed short xpad_abs_pad[] = {
ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */
-1 /* terminating entry */
};
/* used when triggers are mapped to axes */
static const signed short xpad_abs_triggers[] = {
ABS_Z, ABS_RZ, /* triggers left/right */
-1
};
/* Xbox 360 has a vendor-specific class, so we cannot match it with only
* USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we
* match against vendor id as well. Wired Xbox 360 devices have protocol 1,
* wireless controllers have protocol 129. */
#define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \
.match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \
.idVendor = (vend), \
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, \
.bInterfaceSubClass = 93, \
.bInterfaceProtocol = (pr)
#define XPAD_XBOX360_VENDOR(vend) \
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \
{ XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) }
static struct usb_device_id xpad_table [] = {
{ USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */
XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
{ }
};
MODULE_DEVICE_TABLE (usb, xpad_table);
struct usb_xpad {
struct input_dev *dev; /* input device interface */
struct usb_device *udev; /* usb device */
int pad_present;
struct urb *irq_in; /* urb for interrupt in report */
unsigned char *idata; /* input data */
dma_addr_t idata_dma;
struct urb *bulk_out;
unsigned char *bdata;
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct urb *irq_out; /* urb for interrupt out report */
unsigned char *odata; /* output data */
dma_addr_t odata_dma;
struct mutex odata_mutex;
#endif
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
struct xpad_led *led;
#endif
char phys[64]; /* physical device path */
int mapping; /* map d-pad to buttons or to axes */
int xtype; /* type of xbox device */
};
/*
* xpad_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem.
*
* The used report descriptor was taken from ITO Takayukis website:
* http://euc.jp/periphs/xbox-controller.ja.html
*/
static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
/* left stick */
input_report_abs(dev, ABS_X,
(__s16) le16_to_cpup((__le16 *)(data + 12)));
input_report_abs(dev, ABS_Y,
~(__s16) le16_to_cpup((__le16 *)(data + 14)));
/* right stick */
input_report_abs(dev, ABS_RX,
(__s16) le16_to_cpup((__le16 *)(data + 16)));
input_report_abs(dev, ABS_RY,
~(__s16) le16_to_cpup((__le16 *)(data + 18)));
}
/* triggers left/right */
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
input_report_key(dev, BTN_TL2, data[10]);
input_report_key(dev, BTN_TR2, data[11]);
} else {
input_report_abs(dev, ABS_Z, data[10]);
input_report_abs(dev, ABS_RZ, data[11]);
}
/* digital pad */
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
/* dpad as buttons (left, right, up, down) */
input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
} else {
input_report_abs(dev, ABS_HAT0X,
!!(data[2] & 0x08) - !!(data[2] & 0x04));
input_report_abs(dev, ABS_HAT0Y,
!!(data[2] & 0x02) - !!(data[2] & 0x01));
}
/* start/back buttons and stick press left/right */
input_report_key(dev, BTN_START, data[2] & 0x10);
input_report_key(dev, BTN_SELECT, data[2] & 0x20);
input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
/* "analog" buttons A, B, X, Y */
input_report_key(dev, BTN_A, data[4]);
input_report_key(dev, BTN_B, data[5]);
input_report_key(dev, BTN_X, data[6]);
input_report_key(dev, BTN_Y, data[7]);
/* "analog" buttons black, white */
input_report_key(dev, BTN_C, data[8]);
input_report_key(dev, BTN_Z, data[9]);
input_sync(dev);
}
/*
* xpad360_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem. It is version for xbox 360 controller
*
* The used report descriptor was taken from:
* http://www.free60.org/wiki/Gamepad
*/
static void xpad360_process_packet(struct usb_xpad *xpad,
u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
/* digital pad */
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
/* dpad as buttons (left, right, up, down) */
input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04);
input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08);
input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01);
input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02);
} else {
input_report_abs(dev, ABS_HAT0X,
!!(data[2] & 0x08) - !!(data[2] & 0x04));
input_report_abs(dev, ABS_HAT0Y,
!!(data[2] & 0x02) - !!(data[2] & 0x01));
}
/* start/back buttons */
input_report_key(dev, BTN_START, data[2] & 0x10);
input_report_key(dev, BTN_SELECT, data[2] & 0x20);
/* stick press left/right */
input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
/* buttons A,B,X,Y,TL,TR and MODE */
input_report_key(dev, BTN_A, data[3] & 0x10);
input_report_key(dev, BTN_B, data[3] & 0x20);
input_report_key(dev, BTN_X, data[3] & 0x40);
input_report_key(dev, BTN_Y, data[3] & 0x80);
input_report_key(dev, BTN_TL, data[3] & 0x01);
input_report_key(dev, BTN_TR, data[3] & 0x02);
input_report_key(dev, BTN_MODE, data[3] & 0x04);
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
/* left stick */
input_report_abs(dev, ABS_X,
(__s16) le16_to_cpup((__le16 *)(data + 6)));
input_report_abs(dev, ABS_Y,
~(__s16) le16_to_cpup((__le16 *)(data + 8)));
/* right stick */
input_report_abs(dev, ABS_RX,
(__s16) le16_to_cpup((__le16 *)(data + 10)));
input_report_abs(dev, ABS_RY,
~(__s16) le16_to_cpup((__le16 *)(data + 12)));
}
/* triggers left/right */
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
input_report_key(dev, BTN_TL2, data[4]);
input_report_key(dev, BTN_TR2, data[5]);
} else {
input_report_abs(dev, ABS_Z, data[4]);
input_report_abs(dev, ABS_RZ, data[5]);
}
input_sync(dev);
}
/*
* xpad360w_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem. It is version for xbox 360 wireless controller.
*
* Byte.Bit
* 00.1 - Status change: The controller or headset has connected/disconnected
* Bits 01.7 and 01.6 are valid
* 01.7 - Controller present
* 01.6 - Headset present
* 01.1 - Pad state (Bytes 4+) valid
*
*/
static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
/* Presence change */
if (data[0] & 0x08) {
if (data[1] & 0x80) {
xpad->pad_present = 1;
usb_submit_urb(xpad->bulk_out, GFP_ATOMIC);
} else
xpad->pad_present = 0;
}
/* Valid pad data */
if (!(data[1] & 0x1))
return;
xpad360_process_packet(xpad, cmd, &data[4]);
}
static void xpad_irq_in(struct urb *urb)
{
struct usb_xpad *xpad = urb->context;
int retval, status;
status = urb->status;
switch (status) {
case 0:
/* success */
break;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d",
__func__, status);
return;
default:
dbg("%s - nonzero urb status received: %d",
__func__, status);
goto exit;
}
switch (xpad->xtype) {
case XTYPE_XBOX360:
xpad360_process_packet(xpad, 0, xpad->idata);
break;
case XTYPE_XBOX360W:
xpad360w_process_packet(xpad, 0, xpad->idata);
break;
default:
xpad_process_packet(xpad, 0, xpad->idata);
}
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
__func__, retval);
}
static void xpad_bulk_out(struct urb *urb)
{
switch (urb->status) {
case 0:
/* success */
break;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d", __func__, urb->status);
break;
default:
dbg("%s - nonzero urb status received: %d", __func__, urb->status);
}
}
#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS)
static void xpad_irq_out(struct urb *urb)
{
int retval, status;
status = urb->status;
switch (status) {
case 0:
/* success */
return;
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d", __func__, status);
return;
default:
dbg("%s - nonzero urb status received: %d", __func__, status);
goto exit;
}
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
err("%s - usb_submit_urb failed with result %d",
__func__, retval);
}
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
{
struct usb_endpoint_descriptor *ep_irq_out;
int error;
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
return 0;
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->odata_dma);
if (!xpad->odata) {
error = -ENOMEM;
goto fail1;
}
mutex_init(&xpad->odata_mutex);
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_out) {
error = -ENOMEM;
goto fail2;
}
ep_irq_out = &intf->cur_altsetting->endpoint[1].desc;
usb_fill_int_urb(xpad->irq_out, xpad->udev,
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
xpad->odata, XPAD_PKT_LEN,
xpad_irq_out, xpad, ep_irq_out->bInterval);
xpad->irq_out->transfer_dma = xpad->odata_dma;
xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
return 0;
fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
fail1: return error;
}
static void xpad_stop_output(struct usb_xpad *xpad)
{
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX)
usb_kill_urb(xpad->irq_out);
}
static void xpad_deinit_output(struct usb_xpad *xpad)
{
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX) {
usb_free_urb(xpad->irq_out);
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
xpad->odata, xpad->odata_dma);
}
}
#else
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; }
static void xpad_deinit_output(struct usb_xpad *xpad) {}
static void xpad_stop_output(struct usb_xpad *xpad) {}
#endif
#ifdef CONFIG_JOYSTICK_XPAD_FF
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
if (effect->type == FF_RUMBLE) {
__u16 strong = effect->u.rumble.strong_magnitude;
__u16 weak = effect->u.rumble.weak_magnitude;
switch (xpad->xtype) {
case XTYPE_XBOX:
xpad->odata[0] = 0x00;
xpad->odata[1] = 0x06;
xpad->odata[2] = 0x00;
xpad->odata[3] = strong / 256; /* left actuator */
xpad->odata[4] = 0x00;
xpad->odata[5] = weak / 256; /* right actuator */
xpad->irq_out->transfer_buffer_length = 6;
return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
case XTYPE_XBOX360:
xpad->odata[0] = 0x00;
xpad->odata[1] = 0x08;
xpad->odata[2] = 0x00;
xpad->odata[3] = strong / 256; /* left actuator? */
xpad->odata[4] = weak / 256; /* right actuator? */
xpad->odata[5] = 0x00;
xpad->odata[6] = 0x00;
xpad->odata[7] = 0x00;
xpad->irq_out->transfer_buffer_length = 8;
return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);
default:
dbg("%s - rumble command sent to unsupported xpad type: %d",
__func__, xpad->xtype);
return -1;
}
}
return 0;
}
static int xpad_init_ff(struct usb_xpad *xpad)
{
if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX)
return 0;
input_set_capability(xpad->dev, EV_FF, FF_RUMBLE);
return input_ff_create_memless(xpad->dev, NULL, xpad_play_effect);
}
#else
static int xpad_init_ff(struct usb_xpad *xpad) { return 0; }
#endif
#if defined(CONFIG_JOYSTICK_XPAD_LEDS)
#include <linux/leds.h>
struct xpad_led {
char name[16];
struct led_classdev led_cdev;
struct usb_xpad *xpad;
};
static void xpad_send_led_command(struct usb_xpad *xpad, int command)
{
if (command >= 0 && command < 14) {
mutex_lock(&xpad->odata_mutex);
xpad->odata[0] = 0x01;
xpad->odata[1] = 0x03;
xpad->odata[2] = command;
xpad->irq_out->transfer_buffer_length = 3;
usb_submit_urb(xpad->irq_out, GFP_KERNEL);
mutex_unlock(&xpad->odata_mutex);
}
}
static void xpad_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
struct xpad_led *xpad_led = container_of(led_cdev,
struct xpad_led, led_cdev);
xpad_send_led_command(xpad_led->xpad, value);
}
static int xpad_led_probe(struct usb_xpad *xpad)
{
static atomic_t led_seq = ATOMIC_INIT(0);
long led_no;
struct xpad_led *led;
struct led_classdev *led_cdev;
int error;
if (xpad->xtype != XTYPE_XBOX360)
return 0;
xpad->led = led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL);
if (!led)
return -ENOMEM;
led_no = (long)atomic_inc_return(&led_seq) - 1;
snprintf(led->name, sizeof(led->name), "xpad%ld", led_no);
led->xpad = xpad;
led_cdev = &led->led_cdev;
led_cdev->name = led->name;
led_cdev->brightness_set = xpad_led_set;
error = led_classdev_register(&xpad->udev->dev, led_cdev);
if (error) {
kfree(led);
xpad->led = NULL;
return error;
}
/*
* Light up the segment corresponding to controller number
*/
xpad_send_led_command(xpad, (led_no % 4) + 2);
return 0;
}
static void xpad_led_disconnect(struct usb_xpad *xpad)
{
struct xpad_led *xpad_led = xpad->led;
if (xpad_led) {
led_classdev_unregister(&xpad_led->led_cdev);
kfree(xpad_led);
}
}
#else
static int xpad_led_probe(struct usb_xpad *xpad) { return 0; }
static void xpad_led_disconnect(struct usb_xpad *xpad) { }
#endif
static int xpad_open(struct input_dev *dev)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
/* URB was submitted in probe */
if(xpad->xtype == XTYPE_XBOX360W)
return 0;
xpad->irq_in->dev = xpad->udev;
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
return -EIO;
return 0;
}
static void xpad_close(struct input_dev *dev)
{
struct usb_xpad *xpad = input_get_drvdata(dev);
if (xpad->xtype != XTYPE_XBOX360W)
usb_kill_urb(xpad->irq_in);
xpad_stop_output(xpad);
}
static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
{
set_bit(abs, input_dev->absbit);
switch (abs) {
case ABS_X:
case ABS_Y:
case ABS_RX:
case ABS_RY: /* the two sticks */
input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
break;
case ABS_Z:
case ABS_RZ: /* the triggers (if mapped to axes) */
input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
break;
case ABS_HAT0X:
case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */
input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
break;
}
}
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
struct input_dev *input_dev;
struct usb_endpoint_descriptor *ep_irq_in;
int i, error;
for (i = 0; xpad_device[i].idVendor; i++) {
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
(le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
break;
}
xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
input_dev = input_allocate_device();
if (!xpad || !input_dev) {
error = -ENOMEM;
goto fail1;
}
xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->idata_dma);
if (!xpad->idata) {
error = -ENOMEM;
goto fail1;
}
xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_in) {
error = -ENOMEM;
goto fail2;
}
xpad->udev = udev;
xpad->mapping = xpad_device[i].mapping;
xpad->xtype = xpad_device[i].xtype;
if (xpad->xtype == XTYPE_UNKNOWN) {
if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
xpad->xtype = XTYPE_XBOX360W;
else
xpad->xtype = XTYPE_XBOX360;
} else
xpad->xtype = XTYPE_XBOX;
if (dpad_to_buttons)
xpad->mapping |= MAP_DPAD_TO_BUTTONS;
if (triggers_to_buttons)
xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
if (sticks_to_null)
xpad->mapping |= MAP_STICKS_TO_NULL;
}
xpad->dev = input_dev;
usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
input_dev->name = xpad_device[i].name;
input_dev->phys = xpad->phys;
usb_to_input_id(udev, &input_dev->id);
input_dev->dev.parent = &intf->dev;
input_set_drvdata(input_dev, xpad);
input_dev->open = xpad_open;
input_dev->close = xpad_close;
input_dev->evbit[0] = BIT_MASK(EV_KEY);
if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
input_dev->evbit[0] |= BIT_MASK(EV_ABS);
/* set up axes */
for (i = 0; xpad_abs[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs[i]);
}
/* set up standard buttons */
for (i = 0; xpad_common_btn[i] >= 0; i++)
__set_bit(xpad_common_btn[i], input_dev->keybit);
/* set up model-specific ones */
if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
for (i = 0; xpad360_btn[i] >= 0; i++)
__set_bit(xpad360_btn[i], input_dev->keybit);
} else {
for (i = 0; xpad_btn[i] >= 0; i++)
__set_bit(xpad_btn[i], input_dev->keybit);
}
if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
for (i = 0; xpad_btn_pad[i] >= 0; i++)
__set_bit(xpad_btn_pad[i], input_dev->keybit);
} else {
for (i = 0; xpad_abs_pad[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
}
if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
for (i = 0; xpad_btn_triggers[i] >= 0; i++)
__set_bit(xpad_btn_triggers[i], input_dev->keybit);
} else {
for (i = 0; xpad_abs_triggers[i] >= 0; i++)
xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
}
error = xpad_init_output(intf, xpad);
if (error)
goto fail3;
error = xpad_init_ff(xpad);
if (error)
goto fail4;
error = xpad_led_probe(xpad);
if (error)
goto fail5;
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma;
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
error = input_register_device(xpad->dev);
if (error)
goto fail6;
usb_set_intfdata(intf, xpad);
if (xpad->xtype == XTYPE_XBOX360W) {
/*
* Setup the message to set the LEDs on the
* controller when it shows up
*/
xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->bulk_out) {
error = -ENOMEM;
goto fail7;
}
xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
if (!xpad->bdata) {
error = -ENOMEM;
goto fail8;
}
xpad->bdata[2] = 0x08;
switch (intf->cur_altsetting->desc.bInterfaceNumber) {
case 0:
xpad->bdata[3] = 0x42;
break;
case 2:
xpad->bdata[3] = 0x43;
break;
case 4:
xpad->bdata[3] = 0x44;
break;
case 6:
xpad->bdata[3] = 0x45;
}
ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
usb_fill_bulk_urb(xpad->bulk_out, udev,
usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);
/*
* Submit the int URB immediately rather than waiting for open
* because we get status messages from the device whether
* or not any controllers are attached. In fact, it's
* exactly the message that a controller has arrived that
* we're waiting for.
*/
xpad->irq_in->dev = xpad->udev;
error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
if (error)
goto fail9;
}
return 0;
fail9: kfree(xpad->bdata);
fail8: usb_free_urb(xpad->bulk_out);
fail7: input_unregister_device(input_dev);
input_dev = NULL;
fail6: xpad_led_disconnect(xpad);
fail5: if (input_dev)
input_ff_destroy(input_dev);
fail4: xpad_deinit_output(xpad);
fail3: usb_free_urb(xpad->irq_in);
fail2: usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
fail1: input_free_device(input_dev);
kfree(xpad);
return error;
}
static void xpad_disconnect(struct usb_interface *intf)
{
struct usb_xpad *xpad = usb_get_intfdata (intf);
xpad_led_disconnect(xpad);
input_unregister_device(xpad->dev);
xpad_deinit_output(xpad);
if (xpad->xtype == XTYPE_XBOX360W) {
usb_kill_urb(xpad->bulk_out);
usb_free_urb(xpad->bulk_out);
usb_kill_urb(xpad->irq_in);
}
usb_free_urb(xpad->irq_in);
usb_free_coherent(xpad->udev, XPAD_PKT_LEN,
xpad->idata, xpad->idata_dma);
kfree(xpad->bdata);
kfree(xpad);
usb_set_intfdata(intf, NULL);
}
static struct usb_driver xpad_driver = {
.name = "xpad",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
.id_table = xpad_table,
};
static int __init usb_xpad_init(void)
{
return usb_register(&xpad_driver);
}
static void __exit usb_xpad_exit(void)
{
usb_deregister(&xpad_driver);
}
module_init(usb_xpad_init);
module_exit(usb_xpad_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
xpad.ko not found
So I clearly did not look hard enough.
I found this post http://www.androidsim.net/2011/07/how-to-30-connect-xbox360-wireless.html and this thread http://forum.xda-developers.com/gal...krn-modules-xpad-ko-xbox-360-gamepad-t1797439 that provide more light on my issue.
And when I search on my device or inside the $OUT/target repository from my android compiling workspace, I can't find the xpad.ko file.
Either I am not looking at the right place to find it, either it is not compiled by my compilation process !
Investigating further...
so... I modified the config file provided from the source. I used make menuconfig to do so. I built the ROM. It does not boot, like the last ones.
Can't compile a booting ROM anymore
So, I had managed to compile a CM13 ROM supported by Temasek (but not the Temasek rom per see, not so sure).
Then I started to look at the drive issue as explained above.
But now that I kinda know what to do, I can't compile any working ROM (withou modifying anything).
Here is the configuration I have on a DarkenedSky94 workspace :
My local manifest named roomservice.xml is (copy paste from darkenedsky post).
Code:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!--Build-->
<remove-project name="temasek/android_build" />
<project name="DarkenedSky94/android_build" path="build" />
<remove-project name="CyanogenMod/android_packages_apps_AudioFX" />
<!--i9300-->
<project name="DarkenedSky94/android_device_samsung_i9300" path="device/samsung/i9300" remote="github" />
<project name="CyanogenMod/android_device_samsung_smdk4412-common" path="device/samsung/smdk4412-common" remote="github" />
<project name="DarkenedSky94/android_kernel_samsung_smdk4412" path="kernel/samsung/smdk4412" remote="github" />
<project name="CyanogenMod/android_packages_apps_SamsungServiceMode" path="packages/apps/SamsungServiceMode" remote="github" />
<project name="CyanogenMod/android_hardware_samsung" path="hardware/samsung" remote="github" />
<project name="CyanogenMod/android_external_stlport" path="external/stlport" remote="github" />
<project name="TheMuppets/proprietary_vendor_samsung" path="vendor/samsung" remote="github" />
<!--OTA-->
<remove-project name="temasek/OTAUpdates" />
<project name="temasek/OTAUpdates" path="packages/apps/OTAUpdates" revision="aosp-old" />
</manifest>
My common.mk in /device/samsung/smdk4412-common is :
Code:
#
# Copyright (C) 2012 The CyanogenMod Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
COMMON_PATH := device/samsung/smdk4412-common
DEVICE_PACKAGE_OVERLAYS := $(COMMON_PATH)/overlay
PRODUCT_BUILD_PROP_OVERRIDES += BUILD_UTC_DATE=0
$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_full.mk)
# The gps config appropriate for this device
$(call inherit-product, device/common/gps/gps_us_supl.mk)
# Init files
PRODUCT_COPY_FILES := \
$(COMMON_PATH)/rootdir/init.smdk4x12.rc:root/init.smdk4x12.rc \
$(COMMON_PATH)/rootdir/init.smdk4x12.usb.rc:root/init.smdk4x12.usb.rc \
$(COMMON_PATH)/rootdir/init.trace.rc:root/init.trace.rc \
$(COMMON_PATH)/rootdir/ueventd.smdk4x12.rc:root/ueventd.smdk4x12.rc \
$(COMMON_PATH)/rootdir/ueventd.smdk4x12.rc:recovery/root/ueventd.smdk4x12.rc
# Audio
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/audio_effects.conf:system/etc/audio_effects.conf \
$(COMMON_PATH)/configs/audio_policy.conf:system/etc/audio_policy.conf \
$(COMMON_PATH)/audio/silence.wav:system/etc/sound/silence.wav
# Camera FW
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/80cfw:system/etc/init.d/80cfw
# Netflix hack
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/98netflix:system/etc/init.d/98netflix
# Wifi
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/wpa_supplicant_overlay.conf:system/etc/wifi/wpa_supplicant_overlay.conf \
$(COMMON_PATH)/configs/p2p_supplicant_overlay.conf:system/etc/wifi/p2p_supplicant_overlay.conf
PRODUCT_PROPERTY_OVERRIDES += \
wifi.interface=wlan0 \
wifi.supplicant_scan_interval=15
# Gps
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/gps.conf:system/etc/gps.conf
# Packages
PRODUCT_PACKAGES := \
AdvancedDisplay \
audio.a2dp.default \
audio.primary.smdk4x12 \
audio.r_submix.default \
audio.usb.default \
com.android.future.usb.accessory \
# Gello \
gralloc.exynos4 \
hwcomposer.exynos4 \
libfimg \
libnetcmdiface \
libsecion \
libstlport \
libsync \
lights.exynos4 \
macloader \
Snap \
tinymix
# MFC API
PRODUCT_PACKAGES += \
libsecmfcdecapi \
libsecmfcencapi
# OMX
PRODUCT_PACKAGES += \
libstagefrighthw \
libSEC_OMX_Resourcemanager \
libSEC_OMX_Core \
libOMX.SEC.AVC.Decoder \
libOMX.SEC.M4V.Decoder \
libOMX.SEC.WMV.Decoder \
libOMX.SEC.AVC.Encoder \
libOMX.SEC.M4V.Encoder
# libOMX.SEC.VP8.Decoder
PRODUCT_COPY_FILES += \
$(COMMON_PATH)/configs/media_profiles.xml:system/etc/media_profiles.xml \
$(COMMON_PATH)/configs/media_codecs.xml:system/etc/media_codecs.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_audio.xml:system/etc/media_codecs_google_audio.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_telephony.xml:system/etc/media_codecs_google_telephony.xml \
frameworks/av/media/libstagefright/data/media_codecs_google_video.xml:system/etc/media_codecs_google_video.xml
# Filesystem management tools
PRODUCT_PACKAGES += \
make_ext4fs \
setup_fs
# Live Wallpapers
PRODUCT_PACKAGES += \
Galaxy4 \
HoloSpiralWallpaper \
LiveWallpapers \
LiveWallpapersPicker \
MagicSmokeWallpapers \
NoiseField \
PhaseBeam \
VisualizationWallpapers \
librs_jni
# Wifi
PRODUCT_PACKAGES += \
libwpa_client \
hostapd \
dhcpcd.conf \
wpa_supplicant \
wpa_supplicant.conf
# Charger
PRODUCT_PACKAGES += \
charger_res_images
# These are the hardware-specific features
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.bluetooth_le.xml:system/etc/permissions/android.hardware.bluetooth_le.xml \
frameworks/native/data/etc/android.hardware.camera.autofocus.xml:system/etc/permissions/android.hardware.camera.autofocus.xml \
frameworks/native/data/etc/android.hardware.camera.flash-autofocus.xml:system/etc/permissions/android.hardware.camera.flash-autofocus.xml \
frameworks/native/data/etc/android.hardware.camera.front.xml:system/etc/permissions/android.hardware.camera.front.xml \
frameworks/native/data/etc/android.hardware.camera.xml:system/etc/permissions/android.hardware.camera.xml \
frameworks/native/data/etc/android.hardware.location.gps.xml:system/etc/permissions/android.hardware.location.gps.xml \
frameworks/native/data/etc/android.hardware.location.xml:system/etc/permissions/android.hardware.location.xml \
frameworks/native/data/etc/android.hardware.sensor.accelerometer.xml:system/etc/permissions/android.hardware.sensor.accelerometer.xml \
frameworks/native/data/etc/android.hardware.sensor.compass.xml:system/etc/permissions/android.hardware.sensor.compass.xml \
frameworks/native/data/etc/android.hardware.sensor.gyroscope.xml:system/etc/permissions/android.hardware.sensor.gyroscope.xml \
frameworks/native/data/etc/android.hardware.sensor.light.xml:system/etc/permissions/android.hardware.sensor.light.xml \
frameworks/native/data/etc/android.hardware.sensor.proximity.xml:system/etc/permissions/android.hardware.sensor.proximity.xml \
frameworks/native/data/etc/android.hardware.touchscreen.multitouch.jazzhand.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.jazzhand.xml \
frameworks/native/data/etc/android.hardware.touchscreen.multitouch.xml:system/etc/permissions/android.hardware.touchscreen.multitouch.xml \
frameworks/native/data/etc/android.hardware.touchscreen.xml:system/etc/permissions/android.hardware.touchscreen.xml \
frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml \
frameworks/native/data/etc/android.hardware.usb.host.xml:system/etc/permissions/android.hardware.usb.host.xml \
frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml \
frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml \
frameworks/native/data/etc/android.software.sip.voip.xml:system/etc/permissions/android.software.sip.voip.xml \
frameworks/native/data/etc/android.software.sip.xml:system/etc/permissions/android.software.sip.xml
# Feature live wallpaper
PRODUCT_COPY_FILES += \
packages/wallpapers/LivePicker/android.software.live_wallpaper.xml:system/etc/permissions/android.software.live_wallpaper.xml
# Keylayouts
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/configs/excluded-input-devices.xml:system/etc/excluded-input-devices.xml
# Graphics
PRODUCT_PROPERTY_OVERRIDES += \
ro.zygote.disable_gl_preload=1 \
ro.opengles.version=131072 \
ro.bq.gpu_to_cpu_unsupported=1 \
debug.hwui.render_dirty_regions=false
PRODUCT_TAGS += dalvik.gc.type-precise
$(call inherit-product, frameworks/native/build/phone-xhdpi-1024-dalvik-heap.mk)
# Include exynos4 platform specific parts
TARGET_HAL_PATH := hardware/samsung/exynos4/hal
TARGET_OMX_PATH := hardware/samsung/exynos/multimedia/openmax
$(call inherit-product, hardware/samsung/exynos4x12.mk)
# Include non-opensource parts
$(call inherit-product, vendor/samsung/smdk4412-common/common-vendor.mk)
(I removed GELLO from it because always failed to download and breaks the build, did not get why).
Finally, the start of my brunch i9300 is
Code:
The start of brunch i9300 is
Looking for dependencies
Dependencies file not found, bailing out.
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=6.0.1
CM_VERSION=13.0-20160611-UNOFFICIAL-temasek-i9300
TARGET_PRODUCT=cm_i9300
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.2.0-35-generic-x86_64-with-Ubuntu-14.04-trusty
HOST_BUILD_TYPE=release
BUILD_ID=MOB30M
OUT_DIR=/media/poutrathor/MiniRugged_Ext4/TemasekBuilding/android/system/out
============================================
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=6.0.1
CM_VERSION=13.0-20160611-UNOFFICIAL-temasek-i9300
TARGET_PRODUCT=cm_i9300
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.2.0-35-generic-x86_64-with-Ubuntu-14.04-trusty
HOST_BUILD_TYPE=release
BUILD_ID=MOB30M
OUT_DIR=/media/poutrathor/MiniRugged_Ext4/TemasekBuilding/android/system/out
============================================
Which looks good, right ?
But then it failed on this error. When I build the CM13 sources only, no trouble over it.
Code:
make: *** No rule to make target `/media/poutrathor/MiniRugged_Ext4/TemasekBuilding/android/system/out/host/common/obj/JAVA_LIBRARIES/conscrypt-host_intermediates/javalib.jar', needed by `/media/poutrathor/MiniRugged_Ext4/TemasekBuilding/android/system/out/host/common/obj/JAVA_LIBRARIES/signapk_intermediates/javalib.jar'. Stop.
make: *** Waiting for unfinished jobs....
Do you see any issue with this configuration ? I can post the full .repo/manifest if needed (it's long file).
What others settings should I look at ?
Please help me, I am getting mad and obsessed with the issue
Secondary question : How can I be sure I am synchronizing with sources that are working (not in progress). I don't understand how repo handles the tag system over such a large number of repositories/projects.
If I build from CM repo with this local manifest, I still get the same error about conscrypt and signapk :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!--Build-->
<remove-project name="CyanogenMod/android_build" />
<project name="DarkenedSky94/android_build" path="build" />
<remove-project name="CyanogenMod/android_packages_apps_AudioFX" />
<!--i9300-->
<project name="DarkenedSky94/android_device_samsung_i9300" path="device/samsung/i9300" remote="github" />
<project name="CyanogenMod/android_device_samsung_smdk4412-common" path="device/samsung/smdk4412-common" remote="github" />
<project name="DarkenedSky94/android_kernel_samsung_smdk4412" path="kernel/samsung/smdk4412" remote="github" />
<project name="CyanogenMod/android_packages_apps_SamsungServiceMode" path="packages/apps/SamsungServiceMode" remote="github" />
<project name="CyanogenMod/android_hardware_samsung" path="hardware/samsung" remote="github" />
<project name="CyanogenMod/android_external_stlport" path="external/stlport" remote="github" />
<project name="TheMuppets/proprietary_vendor_samsung" path="vendor/samsung" remote="github" />
<!--OTA-->
<!-- <remove-project name="temasek/OTAUpdates" /> -->
<project name="temasek/OTAUpdates" path="packages/apps/OTAUpdates" revision="aosp-old" />
</manifest>
This is not going good at all.
I am compiling a ROM without removing the cyanogenMod/android_build to replace it with Temasek/DarkenedSky_build. Except that CM source with previous local manifest. The conscrypt and signapk error is not happening.
Edit : It did built but it failed to boot. Issue with the surface. Cf log on drive.
Related
Does anyone have any information about how to adjust screen sensitivity under Android, specifricaly Froyo on Nexus One?
I'm trying to research this topic but there seems to be very little information about this. I can't find any tool, script or custom rom that would allow screen sensitivity to be adjusted.
I found a thread talking about doing it for Liqid's touch using script but that's about it. I took a look on the script and I can't move forward with it as the path's script uses do not exists in my Nexus One. If anyone has any experience with this please share. The goal is to make the screen more sensitive then it is as a default.
Thanks.
Thread reference above:
android.modaco.com/content-page/309503/increase-touch-screen-sensitivity-only-tested-on-liquide-1-100-05-based-roms/page/40/
Script:
#!/system/bin/sh
sensitivity=25
noise=25
echo "set sensitivity to $sensitivity"
echo $sensitivity > /sys/devices/platform/i2c-adapter/i2c-0/0-005c/sensitivity
echo "set noise to $noise"
echo $noise > /sys/devices/platform/i2c-adapter/i2c-0/0-005c/noise
echo "done"
Sorry for bringing back something from the dead, but I've been researching about this. Nexus One screen sensitivity is low, compared to other touch screens I've experimented with. I know Nexus One is using a Synaptics board. Digging in the source code of Android, I found that the settings on the device itself are located here:
/system/usr/idc/synaptics-rmi-touchscreen.idc
The contents of the file as per 2.3.7 are these (they are the same since Gingerbread):
# Copyright (C) 2010 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Input Device Calibration File for the Passion touch screen.
#
# These calibration values are derived from empirical measurements
# and may not be appropriate for use with other touch screens.
# Refer to the input device calibration documentation for more details.
#
# Touch Size
touch.touchSize.calibration = pressure
# Tool Size
# Driver reports tool size as a linear width measurement summed over
# all contact points.
#
# Raw width field measures approx. 1 unit per millimeter
# of tool size on the surface where a raw width of 1 corresponds
# to about 17mm of physical size. Given that the display resolution
# is 10px per mm we obtain a scale factor of 10 pixels / unit and
# a bias of 160 pixels. In addition, the raw width represents a
# sum of all contact area so we note this fact in the calibration.
touch.toolSize.calibration = linear
touch.toolSize.linearScale = 10
touch.toolSize.linearBias = 160
touch.toolSize.isSummed = 1
# Pressure
# Driver reports signal strength as pressure.
#
# A normal thumb touch while touching the back of the device
# typically registers about 100 signal strength units although
# this value is highly variable and is sensitive to contact area,
# manner of contact and environmental conditions. We set the
# scale so that a normal touch with good signal strength will be
# reported as having a pressure somewhere in the vicinity of 1.0,
# a featherlight touch will be below 1.0 and a heavy or large touch
# will be above 1.0. We don't expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.source = default
touch.pressure.scale = 0.01
# Size
touch.size.calibration = normalized
# Orientation
touch.orientation.calibration = none
Click to expand...
Click to collapse
Also, in the kernel, the synaptics driver can be configured to be more sensitive. It is located here on the kernel source:
drivers/input/touchscreen/synaptics_i2c_rmi.c
/*
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/synaptics_i2c_rmi.h>
static struct workqueue_struct *synaptics_wq;
struct synaptics_ts_data {
uint16_t addr;
struct i2c_client *client;
struct input_dev *input_dev;
int use_irq;
bool has_relative_report;
struct hrtimer timer;
struct work_struct work;
uint16_t max[2];
int snap_state[2][2];
int snap_down_on[2];
int snap_down_off[2];
int snap_up_on[2];
int snap_up_off[2];
int snap_down[2];
int snap_up[2];
uint32_t flags;
int reported_finger_count;
int8_t sensitivity_adjust;
int (*power)(int on);
struct early_suspend early_suspend;
};
#ifdef CONFIG_HAS_EARLYSUSPEND
static void synaptics_ts_early_suspend(struct early_suspend *h);
static void synaptics_ts_late_resume(struct early_suspend *h);
#endif
static int synaptics_init_panel(struct synaptics_ts_data *ts)
{
int ret;
ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
goto err_page_select_failed;
}
ret = i2c_smbus_write_byte_data(ts->client, 0x41, 0x04); /* Set "No Clip Z" */
if (ret < 0)
printk(KERN_ERR "i2c_smbus_write_byte_data failed for No Clip Z\n");
ret = i2c_smbus_write_byte_data(ts->client, 0x44,
ts->sensitivity_adjust);
if (ret < 0)
pr_err("synaptics_ts: failed to set Sensitivity Adjust\n");
err_page_select_failed:
ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x04); /* page select = 0x04 */
if (ret < 0)
printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
ret = i2c_smbus_write_byte_data(ts->client, 0xf0, 0x81); /* normal operation, 80 reports per second */
if (ret < 0)
printk(KERN_ERR "synaptics_ts_resume: i2c_smbus_write_byte_data failed\n");
return ret;
}
static void synaptics_ts_work_func(struct work_struct *work)
{
int i;
int ret;
int bad_data = 0;
struct i2c_msg msg[2];
uint8_t start_reg;
uint8_t buf[15];
struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work);
int buf_len = ts->has_relative_report ? 15 : 13;
msg[0].addr = ts->client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &start_reg;
start_reg = 0x00;
msg[1].addr = ts->client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = buf_len;
msg[1].buf = buf;
/* printk("synaptics_ts_work_func\n"); */
for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
ret = i2c_transfer(ts->client->adapter, msg, 2);
if (ret < 0) {
printk(KERN_ERR "synaptics_ts_work_func: i2c_transfer failed\n");
bad_data = 1;
} else {
/* printk("synaptics_ts_work_func: %x %x %x %x %x %x" */
/* " %x %x %x %x %x %x %x %x %x, ret %d\n", */
/* buf[0], buf[1], buf[2], buf[3], */
/* buf[4], buf[5], buf[6], buf[7], */
/* buf[8], buf[9], buf[10], buf[11], */
/* buf[12], buf[13], buf[14], ret); */
if ((buf[buf_len - 1] & 0xc0) != 0x40) {
printk(KERN_WARNING "synaptics_ts_work_func:"
" bad read %x %x %x %x %x %x %x %x %x"
" %x %x %x %x %x %x, ret %d\n",
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7],
buf[8], buf[9], buf[10], buf[11],
buf[12], buf[13], buf[14], ret);
if (bad_data)
synaptics_init_panel(ts);
bad_data = 1;
continue;
}
bad_data = 0;
if ((buf[buf_len - 1] & 1) == 0) {
/* printk("read %d coordinates\n", i); */
break;
} else {
int pos[2][2];
int f, a;
int base;
/* int x = buf[3] | (uint16_t)(buf[2] & 0x1f) << 8; */
/* int y = buf[5] | (uint16_t)(buf[4] & 0x1f) << 8; */
int z = buf[1];
int w = buf[0] >> 4;
int finger = buf[0] & 7;
/* int x2 = buf[3+6] | (uint16_t)(buf[2+6] & 0x1f) << 8; */
/* int y2 = buf[5+6] | (uint16_t)(buf[4+6] & 0x1f) << 8; */
/* int z2 = buf[1+6]; */
/* int w2 = buf[0+6] >> 4; */
/* int finger2 = buf[0+6] & 7; */
/* int dx = (int8_t)buf[12]; */
/* int dy = (int8_t)buf[13]; */
int finger2_pressed;
/* printk("x %4d, y %4d, z %3d, w %2d, F %d, 2nd: x %4d, y %4d, z %3d, w %2d, F %d, dx %4d, dy %4d\n", */
/* x, y, z, w, finger, */
/* x2, y2, z2, w2, finger2, */
/* dx, dy); */
base = 2;
for (f = 0; f < 2; f++) {
uint32_t flip_flag = SYNAPTICS_FLIP_X;
for (a = 0; a < 2; a++) {
int p = buf[base + 1];
p |= (uint16_t)(buf[base] & 0x1f) << 8;
if (ts->flags & flip_flag)
p = ts->max[a] - p;
if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
if (ts->snap_state[f][a]) {
if (p <= ts->snap_down_off[a])
p = ts->snap_down[a];
else if (p >= ts->snap_up_off[a])
p = ts->snap_up[a];
else
ts->snap_state[f][a] = 0;
} else {
if (p <= ts->snap_down_on[a]) {
p = ts->snap_down[a];
ts->snap_state[f][a] = 1;
} else if (p >= ts->snap_up_on[a]) {
p = ts->snap_up[a];
ts->snap_state[f][a] = 1;
}
}
}
pos[f][a] = p;
base += 2;
flip_flag <<= 1;
}
base += 2;
if (ts->flags & SYNAPTICS_SWAP_XY)
swap(pos[f][0], pos[f][1]);
}
if (z) {
input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
}
input_report_abs(ts->input_dev, ABS_PRESSURE, z);
input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
input_report_key(ts->input_dev, BTN_TOUCH, finger);
finger2_pressed = finger > 1 && finger != 7;
input_report_key(ts->input_dev, BTN_2, finger2_pressed);
if (finger2_pressed) {
input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]);
input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]);
}
if (!finger)
z = 0;
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[0][0]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[0][1]);
input_mt_sync(ts->input_dev);
if (finger2_pressed) {
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, z);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, pos[1][0]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, pos[1][1]);
input_mt_sync(ts->input_dev);
} else if (ts->reported_finger_count > 1) {
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_mt_sync(ts->input_dev);
}
ts->reported_finger_count = finger;
input_sync(ts->input_dev);
}
}
}
if (ts->use_irq)
enable_irq(ts->client->irq);
}
static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
{
struct synaptics_ts_data *ts = container_of(timer, struct synaptics_ts_data, timer);
/* printk("synaptics_ts_timer_func\n"); */
queue_work(synaptics_wq, &ts->work);
hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
{
struct synaptics_ts_data *ts = dev_id;
/* printk("synaptics_ts_irq_handler\n"); */
disable_irq_nosync(ts->client->irq);
queue_work(synaptics_wq, &ts->work);
return IRQ_HANDLED;
}
static int synaptics_ts_probe(
struct i2c_client *client, const struct i2c_device_id *id)
{
struct synaptics_ts_data *ts;
uint8_t buf0[4];
uint8_t buf1[8];
struct i2c_msg msg[2];
int ret = 0;
uint16_t max_x, max_y;
int fuzz_x, fuzz_y, fuzz_p, fuzz_w;
struct synaptics_i2c_rmi_platform_data *pdata;
unsigned long irqflags;
int inactive_area_left;
int inactive_area_right;
int inactive_area_top;
int inactive_area_bottom;
int snap_left_on;
int snap_left_off;
int snap_right_on;
int snap_right_off;
int snap_top_on;
int snap_top_off;
int snap_bottom_on;
int snap_bottom_off;
uint32_t panel_version;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk(KERN_ERR "synaptics_ts_probe: need I2C_FUNC_I2C\n");
ret = -ENODEV;
goto err_check_functionality_failed;
}
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
if (ts == NULL) {
ret = -ENOMEM;
goto err_alloc_data_failed;
}
INIT_WORK(&ts->work, synaptics_ts_work_func);
ts->client = client;
i2c_set_clientdata(client, ts);
pdata = client->dev.platform_data;
if (pdata)
ts->power = pdata->power;
if (ts->power) {
ret = ts->power(1);
if (ret < 0) {
printk(KERN_ERR "synaptics_ts_probe power on failed\n");
goto err_power_failed;
}
}
ret = i2c_smbus_write_byte_data(ts->client, 0xf4, 0x01); /* device command = reset */
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
/* fail? */
}
{
int retry = 10;
while (retry-- > 0) {
ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
if (ret >= 0)
break;
msleep(100);
}
}
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: Product Major Version %x\n", ret);
panel_version = ret << 8;
ret = i2c_smbus_read_byte_data(ts->client, 0xe5);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: Product Minor Version %x\n", ret);
panel_version |= ret;
ret = i2c_smbus_read_byte_data(ts->client, 0xe3);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: product property %x\n", ret);
if (pdata) {
while (pdata->version > panel_version)
pdata++;
ts->flags = pdata->flags;
ts->sensitivity_adjust = pdata->sensitivity_adjust;
irqflags = pdata->irqflags;
inactive_area_left = pdata->inactive_left;
inactive_area_right = pdata->inactive_right;
inactive_area_top = pdata->inactive_top;
inactive_area_bottom = pdata->inactive_bottom;
snap_left_on = pdata->snap_left_on;
snap_left_off = pdata->snap_left_off;
snap_right_on = pdata->snap_right_on;
snap_right_off = pdata->snap_right_off;
snap_top_on = pdata->snap_top_on;
snap_top_off = pdata->snap_top_off;
snap_bottom_on = pdata->snap_bottom_on;
snap_bottom_off = pdata->snap_bottom_off;
fuzz_x = pdata->fuzz_x;
fuzz_y = pdata->fuzz_y;
fuzz_p = pdata->fuzz_p;
fuzz_w = pdata->fuzz_w;
} else {
irqflags = 0;
inactive_area_left = 0;
inactive_area_right = 0;
inactive_area_top = 0;
inactive_area_bottom = 0;
snap_left_on = 0;
snap_left_off = 0;
snap_right_on = 0;
snap_right_off = 0;
snap_top_on = 0;
snap_top_off = 0;
snap_bottom_on = 0;
snap_bottom_off = 0;
fuzz_x = 0;
fuzz_y = 0;
fuzz_p = 0;
fuzz_w = 0;
}
ret = i2c_smbus_read_byte_data(ts->client, 0xf0);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: device control %x\n", ret);
ret = i2c_smbus_read_byte_data(ts->client, 0xf1);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_byte_data failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: interrupt enable %x\n", ret);
ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
goto err_detect_failed;
}
msg[0].addr = ts->client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = buf0;
buf0[0] = 0xe0;
msg[1].addr = ts->client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 8;
msg[1].buf = buf1;
ret = i2c_transfer(ts->client->adapter, msg, 2);
if (ret < 0) {
printk(KERN_ERR "i2c_transfer failed\n");
goto err_detect_failed;
}
printk(KERN_INFO "synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
buf1[0], buf1[1], buf1[2], buf1[3],
buf1[4], buf1[5], buf1[6], buf1[7]);
ret = i2c_smbus_write_byte_data(ts->client, 0xff, 0x10); /* page select = 0x10 */
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_write_byte_data failed for page select\n");
goto err_detect_failed;
}
ret = i2c_smbus_read_word_data(ts->client, 0x02);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
goto err_detect_failed;
}
ts->has_relative_report = !(ret & 0x100);
printk(KERN_INFO "synaptics_ts_probe: Sensor properties %x\n", ret);
ret = i2c_smbus_read_word_data(ts->client, 0x04);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
goto err_detect_failed;
}
ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
ret = i2c_smbus_read_word_data(ts->client, 0x06);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_read_word_data failed\n");
goto err_detect_failed;
}
ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
if (ts->flags & SYNAPTICS_SWAP_XY)
swap(max_x, max_y);
ret = synaptics_init_panel(ts); /* will also switch back to page 0x04 */
if (ret < 0) {
printk(KERN_ERR "synaptics_init_panel failed\n");
goto err_detect_failed;
}
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
ret = -ENOMEM;
printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
goto err_input_dev_alloc_failed;
}
ts->input_dev->name = "synaptics-rmi-touchscreen";
set_bit(EV_SYN, ts->input_dev->evbit);
set_bit(EV_KEY, ts->input_dev->evbit);
set_bit(BTN_TOUCH, ts->input_dev->keybit);
set_bit(BTN_2, ts->input_dev->keybit);
set_bit(EV_ABS, ts->input_dev->evbit);
inactive_area_left = inactive_area_left * max_x / 0x10000;
inactive_area_right = inactive_area_right * max_x / 0x10000;
inactive_area_top = inactive_area_top * max_y / 0x10000;
inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
snap_left_on = snap_left_on * max_x / 0x10000;
snap_left_off = snap_left_off * max_x / 0x10000;
snap_right_on = snap_right_on * max_x / 0x10000;
snap_right_off = snap_right_off * max_x / 0x10000;
snap_top_on = snap_top_on * max_y / 0x10000;
snap_top_off = snap_top_off * max_y / 0x10000;
snap_bottom_on = snap_bottom_on * max_y / 0x10000;
snap_bottom_off = snap_bottom_off * max_y / 0x10000;
fuzz_x = fuzz_x * max_x / 0x10000;
fuzz_y = fuzz_y * max_y / 0x10000;
ts->snap_down[!!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_left;
ts->snap_up[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x + inactive_area_right;
ts->snap_down[!(ts->flags & SYNAPTICS_SWAP_XY)] = -inactive_area_top;
ts->snap_up[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y + inactive_area_bottom;
ts->snap_down_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_on;
ts->snap_down_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_left_off;
ts->snap_up_on[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_on;
ts->snap_up_off[!!(ts->flags & SYNAPTICS_SWAP_XY)] = max_x - snap_right_off;
ts->snap_down_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_on;
ts->snap_down_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = snap_top_off;
ts->snap_up_on[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_on;
ts->snap_up_off[!(ts->flags & SYNAPTICS_SWAP_XY)] = max_y - snap_bottom_off;
printk(KERN_INFO "synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
printk(KERN_INFO "synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
inactive_area_left, inactive_area_right,
inactive_area_top, inactive_area_bottom);
printk(KERN_INFO "synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
snap_left_on, snap_left_off, snap_right_on, snap_right_off,
snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
input_set_abs_params(ts->input_dev, ABS_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
input_set_abs_params(ts->input_dev, ABS_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0);
input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, -inactive_area_left, max_x + inactive_area_right, fuzz_x, 0);
input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, -inactive_area_top, max_y + inactive_area_bottom, fuzz_y, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, fuzz_p, 0);
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, fuzz_w, 0);
/* ts->input_dev->name = ts->keypad_info->name; */
ret = input_register_device(ts->input_dev);
if (ret) {
printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
goto err_input_register_device_failed;
}
if (client->irq) {
ret = request_irq(client->irq, synaptics_ts_irq_handler, irqflags, client->name, ts);
if (ret == 0) {
ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
if (ret)
free_irq(client->irq, ts);
}
if (ret == 0)
ts->use_irq = 1;
else
dev_err(&client->dev, "request_irq failed\n");
}
if (!ts->use_irq) {
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ts->timer.function = synaptics_ts_timer_func;
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
}
#ifdef CONFIG_HAS_EARLYSUSPEND
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
ts->early_suspend.suspend = synaptics_ts_early_suspend;
ts->early_suspend.resume = synaptics_ts_late_resume;
register_early_suspend(&ts->early_suspend);
#endif
printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
return 0;
err_input_register_device_failed:
input_free_device(ts->input_dev);
err_input_dev_alloc_failed:
err_detect_failed:
err_power_failed:
kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
return ret;
}
static int synaptics_ts_remove(struct i2c_client *client)
{
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
unregister_early_suspend(&ts->early_suspend);
if (ts->use_irq)
free_irq(client->irq, ts);
else
hrtimer_cancel(&ts->timer);
input_unregister_device(ts->input_dev);
kfree(ts);
return 0;
}
static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
int ret;
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
if (ts->use_irq)
disable_irq(client->irq);
else
hrtimer_cancel(&ts->timer);
ret = cancel_work_sync(&ts->work);
if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
enable_irq(client->irq);
ret = i2c_smbus_write_byte_data(ts->client, 0xf1, 0); /* disable interrupt */
if (ret < 0)
printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
ret = i2c_smbus_write_byte_data(client, 0xf0, 0x86); /* deep sleep */
if (ret < 0)
printk(KERN_ERR "synaptics_ts_suspend: i2c_smbus_write_byte_data failed\n");
if (ts->power) {
ret = ts->power(0);
if (ret < 0)
printk(KERN_ERR "synaptics_ts_resume power off failed\n");
}
return 0;
}
static int synaptics_ts_resume(struct i2c_client *client)
{
int ret;
struct synaptics_ts_data *ts = i2c_get_clientdata(client);
if (ts->power) {
ret = ts->power(1);
if (ret < 0)
printk(KERN_ERR "synaptics_ts_resume power on failed\n");
}
synaptics_init_panel(ts);
if (ts->use_irq)
enable_irq(client->irq);
if (!ts->use_irq)
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
else
i2c_smbus_write_byte_data(ts->client, 0xf1, 0x01); /* enable abs int */
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void synaptics_ts_early_suspend(struct early_suspend *h)
{
struct synaptics_ts_data *ts;
ts = container_of(h, struct synaptics_ts_data, early_suspend);
synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
}
static void synaptics_ts_late_resume(struct early_suspend *h)
{
struct synaptics_ts_data *ts;
ts = container_of(h, struct synaptics_ts_data, early_suspend);
synaptics_ts_resume(ts->client);
}
#endif
static const struct i2c_device_id synaptics_ts_id[] = {
{ SYNAPTICS_I2C_RMI_NAME, 0 },
{ }
};
static struct i2c_driver synaptics_ts_driver = {
.probe = synaptics_ts_probe,
.remove = synaptics_ts_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = synaptics_ts_suspend,
.resume = synaptics_ts_resume,
#endif
.id_table = synaptics_ts_id,
.driver = {
.name = SYNAPTICS_I2C_RMI_NAME,
},
};
static int __devinit synaptics_ts_init(void)
{
synaptics_wq = create_singlethread_workqueue("synaptics_wq");
if (!synaptics_wq)
return -ENOMEM;
return i2c_add_driver(&synaptics_ts_driver);
}
static void __exit synaptics_ts_exit(void)
{
i2c_del_driver(&synaptics_ts_driver);
if (synaptics_wq)
destroy_workqueue(synaptics_wq);
}
module_init(synaptics_ts_init);
module_exit(synaptics_ts_exit);
MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
MODULE_LICENSE("GPL");
Click to expand...
Click to collapse
Maybe we can tweak only the .icl file, or we'll have to dig deep into the kernel to improve the responsiveness of this touch screen!
Increased the sensitivity by changing the value:
touch.pressure.scale = 0.01 to touch.pressure.scale = 0.001
in /system/usr/idc/synaptics-rmi-touchscreen.idc
Please use the Q&A Forum for questions Thanks
Moving to Q&A
dferreira said:
Increased the sensitivity by changing the value:
touch.pressure.scale = 0.01 to touch.pressure.scale = 0.001
in /system/usr/idc/synaptics-rmi-touchscreen.idc
Click to expand...
Click to collapse
I just tried this on my MyTouch 4G Slide (htc Doubleshot) running CyanogenMod 10 (20130101). It either works beautifully or it's my imagination. Thanks!!!!!
Screen Sensitivity Enhancement
GandalfTW said:
Does anyone have any information about how to adjust screen sensitivity under Android, specifricaly Froyo on Nexus One?
I'm trying to research this topic but there seems to be very little information about this. I can't find any tool, script or custom rom that would allow screen sensitivity to be adjusted.
I found a thread talking about doing it for Liqid's touch using script but that's about it. I took a look on the script and I can't move forward with it as the path's script uses do not exists in my Nexus One. If anyone has any experience with this please share. The goal is to make the screen more sensitive then it is as a default.
Thanks.
Thread reference above:
android.modaco.com/content-page/309503/increase-touch-screen-sensitivity-only-tested-on-liquide-1-100-05-based-roms/page/40/
Script:
#!/system/bin/sh
sensitivity=25
noise=25
echo "set sensitivity to $sensitivity"
echo $sensitivity > /sys/devices/platform/i2c-adapter/i2c-0/0-005c/sensitivity
echo "set noise to $noise"
echo $noise > /sys/devices/platform/i2c-adapter/i2c-0/0-005c/noise
echo "done"
Click to expand...
Click to collapse
The easiest way you can change your screen sensitivity is by using Screen Booster apps from Google Play. Its really works dude
So let's say I did this and now my screen doesn't work. How can I get it back?
found new method
worked for my zte v9800
Go to System and find build.prop
Then copy the bellow lines and just paste in bulid.prop
# Touch screen calibration and scroll responsiveness
debug.performance.tuning=1
windowsmgr.max_events_per_sec=200
view.touch_slop=2
view.scroll_friction=1.5
view.minimum_fling_velocity=25
ro.max.fling_velocity=12000
ro.min.fling_velocity=8000
ro.min_pointer_dur=8
touch.size.calibration=geometric
touch.size.scale=100
#touch.size.bias=70
touch.pressure.calibration=amplitude
touch.pressure.scale=0.3
Hi..
This is my first post & thread in XDA-Dev, pardon me if i break any rules...
Just tell what i could do to mend the situation and I'll gladly comply.
Intro
Here's what's been bugging me for the past few days.
I'm trying to recompile Sony Ericsson source code archived as x10_x10mini_X10minipro_x8_eclair_2.1.A.0.435.tar.gz to enable a few features :
Swap support
Ad-Hoc wifi
I followed the tutorial on Android Central (http://forum.androidcentral.com/htc-hero-rooting-roms-hacks/8072-how-build-your-own-kernel-package-source.html) except that I'm using SE's kernel codes rather than HTC's.
My Environment
Ubuntu 10.10 over VirtualBox over Windows 7
Using compiler in the Android Toolchain (gcc-4.4.0)
Folders Structure
~/android/source/ : Contain SE Kernel Sources
~/myandroid/ : Contain everything that you should get when you repo git://android.git.kernel.org/platform/manifest.git
Settings
hit export ARCH=arm
hit export CROSS_COMPILE=arm-eabi-
hit export PATH=$PATH:~/myandroid/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
for .config, i used the one from 1.6 as latter version of SE phones does not have /proc/config.gz
What I did
First, i compiled the kernel using the default settings, it completes successfully.
I make clean
When i run make menuconfig I changed
General Setup --> [*] Support for paging of anonymous memory (swap)
System Type --> MSM Board Selection --> [ ] MSM7x27 Mimmi (deselect)
System Type --> MSM Board Selection --> [*] MSM7x27 Shakira (select)
I run make
I was thrown error below.
The Pain In The A$$
Code:
[FONT="Fixedsys"][COLOR="YellowGreen"] CC lib/radix-tree.o
CC lib/ratelimit.o
CC lib/rbtree.o
CC lib/reciprocal_div.o
CC lib/rwsem-spinlock.o
CC lib/sha1.o
CC lib/show_mem.o
CC lib/string.o
CC lib/vsprintf.o
AR lib/lib.a
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/linux/compile.h
UPD include/linux/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1[/COLOR]
[COLOR="Red"]arch/arm/mach-msm/built-in.o: In function `shakira_gpio_event_matrix_func':
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c:90: undefined reference to `semc_gpio_event_matrix_func'
make: *** [.tmp_vmlinux1] Error 1[/COLOR][/FONT]
I did some regex on all files in the SE directory and sub-directory, looking for any mentioning of semc_gpio_event_matrix_func, there are 5 files that has it, namely...
/home/android/android/sources/kernel/arch/arm/mach-msm/board-mimmi-keypad.c
/home/android/android/sources/kernel/arch/arm/mach-msm/board-robyn-keypad.c
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c
/home/android/android/sources/kernel/drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c
/home/android/android/sources/kernel/include/linux/semc/gpio_event.h
Files with silver color is irrelevant, as I'm building the X8. I assume it's safe to ignore them.
my username on the ubuntu is also android, hence the .../android/android/....
Please help me troubleshoot this...
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
I think they give you something so you can use it.
Sent from my Sony Ericsson X8
There should be some way because SE gives us kexec tool even in retail firmware...
Sent from my E15i using XDA App
Asdoos said:
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
Click to expand...
Click to collapse
well if i can't load the whole kernel into the phone, at least i could push custom patched wpa_supplicant.
if it's really impossible, at this date, to use custom ROM on X8 why would then people are toying with the Floyo port?
For now, I'd be happy to just solve patching wpa_supplicant. But since I'm already into this, why not get it done with.
So now there's 3 files that are involved.
herein, are those 3 files, underneath each of which are the files that it #includes and their respective location in the filesystem.
to be honest, i was only looking to play with the config files when i started this.
i've never compiled project this big (i did, but that was looong time ago, and it went without a hitch).
for the past 2 years i only programmed Arduino on C, and occasionally PHPs. So i rarely have to deal much with header files. Also some recreational cracking utilising assembly.
there was a few other errors before this one actually. But it was easily solved by changing <xxxxxx.x> to "xxxxxx.x"
so guys please, please help me.
/home/android/android/sources/kernel/arch/arm/mach-msm/board-shakira-keypad.c
#include <linux/platform_device.h>
location : /home/android/android/sources/kernel/include/linux/platform_device.h
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/gpio_event.h
#include <linux/semc/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/semc/gpio_event.h
#include "board-delta-keypad.h"
location : /home/android/android/sources/kernel/arch/arm/mach-msm/board-delta-keypad.h
#include <mach/semc_rpc_server_handset.h>
location : /home/android/android/sources/kernel/arch/arm/mach-msm/include/mach/semc_rpc_server_handset.h
#include <asm/mach-types.h>
location : /home/android/android/sources/kernel/include/asm/mach-types.h
#include <linux/gpio.h>
location : /home/android/android/sources/kernel/include/linux/gpio.h
/home/android/android/sources/kernel/drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c
#include <linux/kernel.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/gpio.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/hrtimer.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/interrupt.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/wakelock.h>
location : /home/android/android/sources/kernel/include/linux/
/home/android/android/sources/kernel/include/linux/semc/gpio_event.h
#include <linux/gpio_event.h>
location : /home/android/android/sources/kernel/include/linux/
#include <linux/input.h>
location : /home/android/android/sources/kernel/include/linux/
see anything?
I would assume any files with the word keypad are referring to the mini10 pro's slide out keyboard. Your x8 doesn't have one so try and remove from the build process.
Either way the bootloader is locked so I'm not really sure how you will push this onto the phone in the first place.
If you do succeed let us know.
Edit: gpio and wakelock events are probably directed to the hardware switch when the keyboard is opened or closed.
Sent from my Sony Ericsson X8 using XDA App
biglama said:
I would assume any files with the word keypad are referring to the mini10 pro's slide out keyboard. Your x8 doesn't have one so try and remove from the build process.
Either way the bootloader is locked so I'm not really sure how you will push this onto the phone in the first place.
If you do succeed let us know.
Edit: gpio and wakelock events are probably directed to the hardware switch when the keyboard is opened or closed.
Sent from my Sony Ericsson X8 using XDA App
Click to expand...
Click to collapse
in board-shakira-keypad.c, the keys that it governs are the volume up/down, cameray, back, menu and home keys. nothing more, nothing less.
so i'm pretty sure it is for x8.
I'll post the content of the file later.
undefined reference to `semc_gpio_event_matrix_func'
Click to expand...
Click to collapse
can you just look in semc_gpio_matrix.c and add a prototype for that function into board-shakira-keypad.c if it's not provided in any of the other headers.
Source - semc_gpio_matrix.c
as said, the source files...
semc_gpio_matrix.c
Code:
/* drivers/misc/semc/gpio_matrix/gpio_matrix.c
*
* Copyright (C) 2010 Sony Ericsson Mobile Communications AB
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Based upon kernel/drivers/input/misc/gpio_matrix.c
*/
#include <linux/kernel.h>
#include <linux/gpio.h>
#include <linux/gpio_event.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
struct gpio_kp {
struct gpio_event_input_devs *input_devs;
struct gpio_event_matrix_info *keypad_info;
struct hrtimer timer;
struct wake_lock wake_lock;
int current_output;
unsigned int use_irq:1;
unsigned int key_state_changed:1;
unsigned int last_key_state_changed:1;
unsigned int some_keys_pressed:2;
unsigned long keys_pressed[0];
};
static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
{
struct gpio_event_matrix_info *mi = kp->keypad_info;
int key_index = out * mi->ninputs + in;
unsigned short keyentry = mi->keymap[key_index];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (!test_bit(keycode, kp->input_devs->dev[dev]->key)) {
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
"cleared\n", keycode, out, in,
mi->output_gpios[out], mi->input_gpios[in]);
__clear_bit(key_index, kp->keys_pressed);
} else {
if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
"not cleared\n", keycode, out, in,
mi->output_gpios[out], mi->input_gpios[in]);
}
}
static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
{
int rv = 0;
int key_index;
key_index = out * kp->keypad_info->ninputs + in;
while (out < kp->keypad_info->noutputs) {
if (test_bit(key_index, kp->keys_pressed)) {
rv = 1;
clear_phantom_key(kp, out, in);
}
key_index += kp->keypad_info->ninputs;
out++;
}
return rv;
}
static void remove_phantom_keys(struct gpio_kp *kp)
{
int out, in, inp;
int key_index;
if (kp->some_keys_pressed < 3)
return;
for (out = 0; out < kp->keypad_info->noutputs; out++) {
inp = -1;
key_index = out * kp->keypad_info->ninputs;
for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
if (test_bit(key_index, kp->keys_pressed)) {
if (inp == -1) {
inp = in;
continue;
}
if (inp >= 0) {
if (!restore_keys_for_input(kp, out + 1,
inp))
break;
clear_phantom_key(kp, out, inp);
inp = -2;
}
restore_keys_for_input(kp, out, in);
}
}
}
}
static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
{
struct gpio_event_matrix_info *mi = kp->keypad_info;
int pressed = test_bit(key_index, kp->keys_pressed);
unsigned short keyentry = mi->keymap[key_index];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (pressed != test_bit(keycode, kp->input_devs->dev[dev]->key)) {
if (keycode == KEY_RESERVED) {
if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
pr_info("gpiomatrix: unmapped key, %d-%d "
"(%d-%d) changed to %d\n",
out, in, mi->output_gpios[out],
mi->input_gpios[in], pressed);
} else {
if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
"changed to %d\n", keycode,
out, in, mi->output_gpios[out],
mi->input_gpios[in], pressed);
if (mi->info.event)
mi->info.event(kp->input_devs, &mi->info, NULL, dev, 0,
keycode, pressed);
else
input_report_key(kp->input_devs->dev[dev], keycode, pressed);
}
}
}
static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
{
int out, in;
int key_index;
int gpio;
struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
struct gpio_event_matrix_info *mi = kp->keypad_info;
unsigned gpio_keypad_flags = mi->flags;
unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
out = kp->current_output;
if (out == mi->noutputs) {
out = 0;
kp->last_key_state_changed = kp->key_state_changed;
kp->key_state_changed = 0;
kp->some_keys_pressed = 0;
} else {
key_index = out * mi->ninputs;
for (in = 0; in < mi->ninputs; in++, key_index++) {
gpio = mi->input_gpios[in];
if (gpio_get_value(gpio) ^ !polarity) {
if (kp->some_keys_pressed < 3)
kp->some_keys_pressed++;
kp->key_state_changed |= !__test_and_set_bit(
key_index, kp->keys_pressed);
} else
kp->key_state_changed |= __test_and_clear_bit(
key_index, kp->keys_pressed);
}
gpio = mi->output_gpios[out];
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(gpio, !polarity);
else
gpio_direction_input(gpio);
out++;
}
kp->current_output = out;
if (out < mi->noutputs) {
gpio = mi->output_gpios[out];
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(gpio, polarity);
else
gpio_direction_output(gpio, polarity);
hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
if (kp->key_state_changed) {
hrtimer_start(&kp->timer, mi->debounce_delay,
HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
kp->key_state_changed = kp->last_key_state_changed;
}
if (kp->key_state_changed) {
if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
remove_phantom_keys(kp);
key_index = 0;
for (out = 0; out < mi->noutputs; out++)
for (in = 0; in < mi->ninputs; in++, key_index++)
report_key(kp, key_index, out, in);
}
if (!kp->use_irq || kp->some_keys_pressed) {
hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
return HRTIMER_NORESTART;
}
/* No keys are pressed, reenable interrupt */
for (out = 0; out < mi->noutputs; out++) {
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(mi->output_gpios[out], polarity);
else
gpio_direction_output(mi->output_gpios[out], polarity);
}
for (in = 0; in < mi->ninputs; in++)
enable_irq(gpio_to_irq(mi->input_gpios[in]));
wake_unlock(&kp->wake_lock);
return HRTIMER_NORESTART;
}
static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
{
int i;
struct gpio_kp *kp = dev_id;
struct gpio_event_matrix_info *mi = kp->keypad_info;
unsigned gpio_keypad_flags = mi->flags;
if (!kp->use_irq) /* ignore interrupt while registering the handler */
return IRQ_HANDLED;
for (i = 0; i < mi->ninputs; i++)
disable_irq(gpio_to_irq(mi->input_gpios[i]));
for (i = 0; i < mi->noutputs; i++) {
if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
gpio_set_value(mi->output_gpios[i],
!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
else
gpio_direction_input(mi->output_gpios[i]);
}
wake_lock(&kp->wake_lock);
hrtimer_start(&kp->timer, ktime_set(0, 10000), HRTIMER_MODE_REL);
return IRQ_HANDLED;
}
static int gpio_keypad_request_irqs(struct gpio_kp *kp)
{
int i;
int err;
unsigned int irq;
unsigned long request_flags;
struct gpio_event_matrix_info *mi = kp->keypad_info;
switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
default:
request_flags = IRQF_TRIGGER_FALLING;
break;
case GPIOKPF_ACTIVE_HIGH:
request_flags = IRQF_TRIGGER_RISING;
break;
case GPIOKPF_LEVEL_TRIGGERED_IRQ:
request_flags = IRQF_TRIGGER_LOW;
break;
case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
request_flags = IRQF_TRIGGER_HIGH;
break;
}
for (i = 0; i < mi->ninputs; i++) {
err = irq = gpio_to_irq(mi->input_gpios[i]);
if (err < 0)
goto err_gpio_get_irq_num_failed;
err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
"gpio_kp", kp);
if (err) {
pr_err("gpiomatrix: request_irq failed for input %d, "
"irq %d\n", mi->input_gpios[i], irq);
goto err_request_irq_failed;
}
disable_irq(irq);
}
return 0;
for (i = mi->noutputs - 1; i >= 0; i--) {
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
err_request_irq_failed:
err_gpio_get_irq_num_failed:
;
}
return err;
}
int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
struct gpio_event_info *info, void **data, int func)
{
int i;
int err;
int key_count;
struct gpio_kp *kp;
struct gpio_event_matrix_info *mi;
mi = container_of(info, struct gpio_event_matrix_info, info);
if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
/* TODO: disable scanning */
return 0;
}
if (func == GPIO_EVENT_FUNC_INIT) {
if (mi->keymap == NULL ||
mi->input_gpios == NULL ||
mi->output_gpios == NULL) {
err = -ENODEV;
pr_err("gpiomatrix: Incomplete pdata\n");
goto err_invalid_platform_data;
}
key_count = mi->ninputs * mi->noutputs;
*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
BITS_TO_LONGS(key_count), GFP_KERNEL);
if (kp == NULL) {
err = -ENOMEM;
pr_err("gpiomatrix: Failed to allocate private data\n");
goto err_kp_alloc_failed;
}
kp->input_devs = input_devs;
kp->keypad_info = mi;
for (i = 0; i < key_count; i++) {
unsigned short keyentry = mi->keymap[i];
unsigned short keycode = keyentry & MATRIX_KEY_MASK;
unsigned short dev = keyentry >> MATRIX_CODE_BITS;
if (dev >= input_devs->count) {
pr_err("gpiomatrix: bad device index %d >= "
"%d for key code %d\n",
dev, input_devs->count, keycode);
err = -EINVAL;
goto err_bad_keymap;
}
if (keycode && keycode <= KEY_MAX)
input_set_capability(input_devs->dev[dev],
EV_KEY, keycode);
}
for (i = 0; i < mi->noutputs; i++) {
if (gpio_cansleep(mi->output_gpios[i])) {
pr_err("gpiomatrix: unsupported output gpio %d,"
" can sleep\n", mi->output_gpios[i]);
err = -EINVAL;
goto err_request_output_gpio_failed;
}
err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
if (err) {
pr_err("gpiomatrix: gpio_request failed for "
"output %d\n", mi->output_gpios[i]);
goto err_request_output_gpio_failed;
}
if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
err = gpio_direction_output(mi->output_gpios[i],
!(mi->flags & GPIOKPF_ACTIVE_HIGH));
else
err = gpio_direction_input(mi->output_gpios[i]);
if (err) {
pr_err("gpiomatrix: gpio_configure failed for "
"output %d\n", mi->output_gpios[i]);
goto err_output_gpio_configure_failed;
}
}
for (i = 0; i < mi->ninputs; i++) {
err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
if (err) {
pr_err("gpiomatrix: gpio_request failed for "
"input %d\n", mi->input_gpios[i]);
goto err_request_input_gpio_failed;
}
err = gpio_direction_input(mi->input_gpios[i]);
if (err) {
pr_err("gpiomatrix: gpio_direction_input failed"
" for input %d\n", mi->input_gpios[i]);
goto err_gpio_direction_input_failed;
}
}
kp->current_output = mi->noutputs;
kp->key_state_changed = 1;
hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
kp->timer.function = gpio_keypad_timer_func;
wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
err = gpio_keypad_request_irqs(kp);
kp->use_irq = err == 0;
pr_info("SEMC GPIO Matrix Keypad Driver: Start keypad matrix for "
"%s%s in %s mode\n", input_devs->dev[0]->name,
(input_devs->count > 1) ? "..." : "",
kp->use_irq ? "interrupt" : "polling");
if (kp->use_irq)
wake_lock(&kp->wake_lock);
hrtimer_start(&kp->timer, ktime_set(0, 10000),
HRTIMER_MODE_REL);
return 0;
}
err = 0;
kp = *data;
if (kp->use_irq)
for (i = mi->noutputs - 1; i >= 0; i--)
free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
hrtimer_cancel(&kp->timer);
wake_lock_destroy(&kp->wake_lock);
for (i = mi->noutputs - 1; i >= 0; i--) {
err_gpio_direction_input_failed:
gpio_free(mi->input_gpios[i]);
err_request_input_gpio_failed:
;
}
for (i = mi->noutputs - 1; i >= 0; i--) {
err_output_gpio_configure_failed:
gpio_free(mi->output_gpios[i]);
err_request_output_gpio_failed:
;
}
err_bad_keymap:
kfree(kp);
err_kp_alloc_failed:
err_invalid_platform_data:
return err;
}
Source - board-shakira-keypad.c & linux/semc/gpio_event.h
board-shakira-keypad.c
the scandalous line 90 is highlighted in red.
Code:
/*
* Copyright (C) 2009 SEMC
* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
* Author: Daniel Nygren <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/platform_device.h>
#include <linux/gpio_event.h>
#include <linux/semc/gpio_event.h>
#include "board-delta-keypad.h"
#include <mach/semc_rpc_server_handset.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
#define DBG(X)
static unsigned int keypad_row_gpios[] = { 31 };
static unsigned int keypad_col_gpios[] = { 36, 37, 38, 39, 40, 41 };
static atomic_t driver_up_and_running = ATOMIC_INIT(0);
static struct gpio_event_input_devs *kbd_input_dev;
#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(keypad_col_gpios) + (col))
static const unsigned short keypad_keymap_shakira[ARRAY_SIZE(keypad_col_gpios) *
ARRAY_SIZE(keypad_row_gpios)] = {
[KEYMAP_INDEX(0, 0)] = KEY_BACK, /* Left */
[KEYMAP_INDEX(0, 1)] = KEY_HOME, /* Middle */
[KEYMAP_INDEX(0, 2)] = KEY_MENU, /* Right */
[KEYMAP_INDEX(0, 3)] = KEY_VOLUMEUP,
[KEYMAP_INDEX(0, 4)] = KEY_VOLUMEDOWN,
[KEYMAP_INDEX(0, 5)] = KEY_CAMERA, /* Camera Snap */
};
static const unsigned short wakeup_inputs[ARRAY_SIZE(keypad_col_gpios)] = {
0,
1, /* KEY_HOME */
0,
1, /* KEY_VOLUMEUP */
1, /* KEY_VOLUMEDOWN */
0,
};
static unsigned short w_enabled_inputs[ARRAY_SIZE(keypad_col_gpios)];
static void configure_wakeup_inputs(const unsigned short *wi)
{
int i;
for (i = 0; i < ARRAY_SIZE(keypad_col_gpios); i++) {
if (w_enabled_inputs[i] == wi[i])
continue;
if (set_irq_wake(gpio_to_irq(keypad_col_gpios[i]), wi[i])) {
printk(KERN_ERR "%s: set_irq_wake failed for GPIO %d\n",
__func__, keypad_col_gpios[i]);
} else {
DBG(printk(KERN_DEBUG
"%s: set_irq_wake=%d for GPIO %d\n",
__func__, wi[i], keypad_col_gpios[i]);)
w_enabled_inputs[i] = wi[i];
}
}
}
static int shakira_gpio_event_matrix_func(
struct gpio_event_input_devs *input_devs,
struct gpio_event_info *info,
void **data, int func)
{
if (func == GPIO_EVENT_FUNC_INIT) {
struct input_dev *input_dev = input_devs->dev[0];
kbd_input_dev = input_devs;
input_set_capability(input_dev, EV_KEY, KEY_POWER);
input_set_capability(input_dev, EV_KEY, KEY_END);
atomic_set(&driver_up_and_running, 1);
}
if (func == GPIO_EVENT_FUNC_UNINIT)
atomic_set(&driver_up_and_running, 0);
configure_wakeup_inputs(wakeup_inputs);
return [COLOR="Red"]semc_gpio_event_matrix_func(input_devs, info, data, func)[/COLOR];
}
/* Shakira keypad platform device information */
static struct gpio_event_matrix_info shakira_keypad_matrix_info = {
.info.func = shakira_gpio_event_matrix_func,
.keymap = keypad_keymap_shakira,
.output_gpios = keypad_row_gpios,
.input_gpios = keypad_col_gpios,
.noutputs = ARRAY_SIZE(keypad_row_gpios),
.ninputs = ARRAY_SIZE(keypad_col_gpios),
.settle_time.tv.nsec = 0,
.poll_time.tv.nsec = 20 * NSEC_PER_MSEC,
.flags = GPIOKPF_LEVEL_TRIGGERED_IRQ |
GPIOKPF_PRINT_UNMAPPED_KEYS
};
static struct gpio_event_info *shakira_keypad_info[] = {
&shakira_keypad_matrix_info.info
};
static struct gpio_event_platform_data shakira_keypad_data = {
.name = "shakira_keypad",
.info = shakira_keypad_info,
.info_count = ARRAY_SIZE(shakira_keypad_info)
};
struct platform_device keypad_device_shakira = {
.name = GPIO_EVENT_DEV_NAME,
.id = -1,
.dev = {
.platform_data = &shakira_keypad_data,
},
};
struct platform_device *get_keypad_device_delta(void)
{
return &keypad_device_shakira;
}
void keypad_rpc_key_callback(uint32_t key, uint32_t event)
{
if (!atomic_read(&driver_up_and_running)) {
DBG(printk(KERN_DEBUG "%s: Power key ignored, driver"
" not ready\n", __func__));
return;
}
switch (key) {
case HS_PWR_K:
key = KEY_POWER;
break;
case HS_END_K:
key = KEY_END;
break;
default:
return;
}
DBG(printk(KERN_DEBUG "%s: reporting key (code %d, value %d)\n",
__func__, key, event != HS_REL_K);)
input_report_key(kbd_input_dev->dev[0], key, event != HS_REL_K);
}
gpio_event.h
Code:
#ifndef _SEMC_GPIO_EVENT_H_
#define _SEMC_GPIO_EVENT_H_
#include <linux/gpio_event.h>
#include <linux/input.h>
int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
int semc_gpio_event_input_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
#endif /*_SEMC_GPIO_EVENT_H_*/
ivorh said:
can you just look in semc_gpio_matrix.c and add a prototype for that function into board-shakira-keypad.c if it's not provided in any of the other headers.
Click to expand...
Click to collapse
Seems like linux/semc/gpio_event.h already declared the prototype. That's all that it does.
i think i know the culprit....
board-shakira-keypad.c calls semc/gpio_event.h to declare the prototype.
but nowhere in those two files have the function actually defined.
The only file that have the function defined, semc_gpio_matrix.c, is not called by any other file.
How come SonyEricsson release such source files? is this not the final set that they use to compile the binaries on our phones?
My question now :
is it okay if i edit board-shakira-keypad.c into something like this :
Code:
#include <linux/platform_device.h>
#include <linux/gpio_event.h>
#include <linux/semc/gpio_event.h>
[COLOR="Red"][B]#include "../../../drivers/misc/semc/gpio_matrix/semc_gpio_matrix.c"[/B][/COLOR]
#include "board-delta-keypad.h"
#include <mach/semc_rpc_server_handset.h>
#include <asm/mach-types.h>
#include <linux/gpio.h>
compilation success this way.
however should i tell the compiler/makefile to find the symbol in the object file of semc_gpio_matrix.c instead?
there's no object file in the folder that contains semc_gpio_matrix.c, except for built-in.o. What should i do?
how about putting a line on top:
extern int semc_gpio_event_matrix_func(struct gpio_event_input_devs *input_dev,
struct gpio_event_info *info, void **data, int func);
And modify the makefile to compile and link the semc_gpio_matrix.c and it object file.
i_hate_sonyericsson said:
if it's really impossible, at this date, to use custom ROM on X8 why would then people are toying with the Floyo port?
Click to expand...
Click to collapse
Rom <> kernel. What they're doing is all BUT the kernel. Making drivers and libraries run on SEMC supplied kernel. I don't know much about low-level on the phone, but it's not like the google dev phones. The bootloader is very different. My guess is it's more like old SEMC phones. The google dev phones boot more like a pc. This is why there's no tether support on these ROMs.
There's tools for flashing files to the device, so I guess if you're able to make compatible files you'll get the kernel in there. Maybe have a word with the creators of the x10flash tool.
Simple!!!!
Asdoos said:
So nice to see someone dev the kernel and I`'m sorry to say I can't help but i'm interested how you wan't to flash the kernel. Isn't it locked by SE to flash a custom kerneL?
Click to expand...
Click to collapse
The answer is so simple...convert the kernel to .sin, then flash it with bin4ry's flasher
Nobody has try this.
Rename sin to img make changes img to sin flash
Sent from my X8
If that was so simple then multitouch would be the first thing done to the phone... Sin files are signed and hashed, if you change them signature becomes invalid and phone won't accept the file...
Sent from my X8, so sorry for gramatical inaccuracy
i think i took the wrong approach in learning system development for android....
i think i should have started via the kitchen section to better and easier understand the low level inner working of the system..
plus, for someone that comes from the Windows world still got much to learn about how things work in Linux world.
Can someone give me link for working to565 program which helps convert raw image files to rle ?
1. Need linux.
2. Script. Name Do.sh
Code:
#!/bin/sh
convert -depth 8 logo.png rgb:logo.raw
./to565 -rle < logo.raw > initlogo.rle
And source. Name to565.c
Code:
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define to565(r,g,b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define from565_r(x) ((((x) >> 11) & 0x1f) * 255 / 31)
#define from565_g(x) ((((x) >> 5) & 0x3f) * 255 / 63)
#define from565_b(x) (((x) & 0x1f) * 255 / 31)
void to_565_raw(void)
{
unsigned char in[3];
unsigned short out;
while(read(0, in, 3) == 3) {
out = to565(in[0],in[1],in[2]);
write(1, &out, 2);
}
return;
}
void to_565_raw_dither(int width)
{
unsigned char in[3];
unsigned short out;
int i = 0;
int e;
int* error = malloc((width+2) * 3 * sizeof(int));
int* next_error = malloc((width+2) * 3 * sizeof(int));
memset(error, 0, (width+2) * 3 * sizeof(int));
memset(next_error, 0, (width+2) * 3 * sizeof(int));
error += 3; // array goes from [-3..((width+1)*3+2)]
next_error += 3;
while(read(0, in, 3) == 3) {
int r = in[0] + error[i*3+0];
int rb = (r < 0) ? 0 : ((r > 255) ? 255 : r);
int g = in[1] + error[i*3+1];
int gb = (g < 0) ? 0 : ((g > 255) ? 255 : g);
int b = in[2] + error[i*3+2];
int bb = (b < 0) ? 0 : ((b > 255) ? 255 : b);
out = to565(rb, gb, bb);
write(1, &out, 2);
#define apply_error(ch) { \
next_error[(i-1)*3+ch] += e * 3 / 16; \
next_error[(i)*3+ch] += e * 5 / 16; \
next_error[(i+1)*3+ch] += e * 1 / 16; \
error[(i+1)*3+ch] += e - ((e*1/16) + (e*3/16) + (e*5/16)); \
}
e = r - from565_r(out);
apply_error(0);
e = g - from565_g(out);
apply_error(1);
e = b - from565_b(out);
apply_error(2);
#undef apply_error
++i;
if (i == width) {
// error <- next_error; next_error <- 0
int* temp = error; error = next_error; next_error = temp;
memset(next_error, 0, (width+1) * 3 * sizeof(int));
i = 0;
}
}
free(error-3);
free(next_error-3);
return;
}
void to_565_rle(void)
{
unsigned char in[3];
unsigned short last, color, count;
unsigned total = 0;
count = 0;
while(read(0, in, 3) == 3) {
color = to565(in[0],in[1],in[2]);
if (count) {
if ((color == last) && (count != 65535)) {
count++;
continue;
} else {
write(1, &count, 2);
write(1, &last, 2);
total += count;
}
}
last = color;
count = 1;
}
if (count) {
write(1, &count, 2);
write(1, &last, 2);
total += count;
}
fprintf(stderr,"%d pixels\n",total);
}
int main(int argc, char **argv)
{
if ((argc == 2) && (!strcmp(argv[1],"-rle"))) {
to_565_rle();
} else {
if (argc > 2 && (!strcmp(argv[1], "-w"))) {
to_565_raw_dither(atoi(argv[2]));
} else {
to_565_raw();
}
}
return 0;
}
Then build.
Code:
gcc -o to565 to565.c
Can you put the to565 program in $PATH?
Will the to565 program work if you put it in the $PATH?
Hi everybody!
I wrote simple server on android with NDK, which will work on port 8888 on android emulator, but i can't connect to it from my client on the host machine.
I added <uses-permission android:name="android.permission.INTERNET"/> in manifest.
I tried to make redirection with telnet:
telnet localhost 5554
redir add tcp:6666:8888
Here code of server:
#include <string.h>
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char* client_message;
int LEN = 512;
client_message = "I am android server";
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
return (*env)->NewStringUTF(env, "Could not create socket");
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
return (*env)->NewStringUTF(env, "bind failed. Error");
}
listen(socket_desc , 3);
c = sizeof(struct sockaddr_in);
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
return (*env)->NewStringUTF(env, "accept failed");
}
while( (read_size = recv(client_sock , buf , 2*LEN+1 , 0)) > 0 )
{
write(client_sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
return (*env)->NewStringUTF(env, "Client disconnected");
}
else if(read_size == -1)
{
return (*env)->NewStringUTF(env, "recv failed");
}
return (*env)->NewStringUTF(env, "Server closed");
}
And code of client on host machine:
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int host_port= 6666;
char* host_name= "localhost";
unsigned short wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )) {
fprintf(stderr, "Could not find useable sock dll %d\n",WSAGetLastError());
return 0;
}
int hsock;
int * p_int ;
hsock = socket(AF_INET, SOCK_STREAM, 0);
if(hsock == -1){
printf("Error initializing socket %d\n",WSAGetLastError());
return 0;
}
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n", WSAGetLastError());
free(p_int);
return 0;
}
free(p_int);
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = inet_addr(host_name);
cout<<"client ready\n";
if( connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == SOCKET_ERROR ){
fprintf(stderr, "Error connecting socket %d\n", WSAGetLastError()); getchar();
return 0;
}
cout<<"connected to server\n";
char buffer[1024];
int buffer_len = 1024;
int bytecount;
int c;
memset(buffer, '\0', buffer_len);
for(char* p=buffer ; (c=getch())!=13 ; p++){
printf("%c", c);
*p = c;
}
if( (bytecount=send(hsock, buffer, strlen(buffer),0))==SOCKET_ERROR){
fprintf(stderr, "Error sending data %d\n", WSAGetLastError());
return 0;
}
printf("Sent bytes %d\n", bytecount);
if((bytecount = recv(hsock, buffer, buffer_len, 0))==SOCKET_ERROR){
fprintf(stderr, "Error receiving data %d\n", WSAGetLastError());
return 0;
}
printf("Recieved bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
closesocket(hsock);
return 0;
}
Solved!
I happend because my windows firewall blocked this port (in my case 6666) and client couldn't connect to server on emulator
to unlock port in windows - open firewall extra options and add rule for income connections (free for all)
I am trying to add Thundeplug to my hotplug. Heres the code and error.
Code:
/* Copyright (c) 2015, Varun Chitre <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A simple hotplugging driver.
* Compatible from dual core CPUs to Octa Core CPUs
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/lcd_notify.h>
#include <linux/cpufreq.h>
#include "thunderplug.h"
#define DEBUG 0
#define THUNDERPLUG "thunderplug"
#define DRIVER_VERSION 5
#define DRIVER_SUBVER 0
#define DEFAULT_CPU_LOAD_THRESHOLD (65)
#define MIN_CPU_LOAD_THRESHOLD (10)
#define HOTPLUG_ENABLED (0)
#define DEFAULT_HOTPLUG_STYLE HOTPLUG_SCHED
#define DEFAULT_SCHED_MODE BALANCED
#define DEF_SAMPLING_MS (500)
#define MIN_SAMLING_MS (50)
#define MIN_CPU_UP_TIME (750)
#define TOUCH_BOOST_ENABLED (0)
static bool isSuspended = false;
struct notifier_block lcd_worker;
static int suspend_cpu_num = 2, resume_cpu_num = (NR_CPUS -1);
static int endurance_level = 0;
static int core_limit = NR_CPUS;
static int now[8], last_time[8];
static int sampling_time = DEF_SAMPLING_MS;
static int load_threshold = DEFAULT_CPU_LOAD_THRESHOLD;
static int stop_boost = 0;
struct cpufreq_policy old_policy[NR_CPUS];
#ifdef CONFIG_SCHED_HMP
static int tplug_hp_style = DEFAULT_HOTPLUG_STYLE;
#else
static int tplug_hp_enabled = HOTPLUG_ENABLED;
#endif
static int tplug_sched_mode = DEFAULT_SCHED_MODE;
static int touch_boost_enabled = TOUCH_BOOST_ENABLED;
static struct workqueue_struct *tplug_wq;
static struct delayed_work tplug_work;
static struct workqueue_struct *tplug_boost_wq;
static struct delayed_work tplug_boost;
static struct workqueue_struct *tplug_resume_wq;
static struct delayed_work tplug_resume_work;
static unsigned int last_load[8] = { 0 };
struct cpu_load_data {
u64 prev_cpu_idle;
u64 prev_cpu_wall;
unsigned int avg_load_maxfreq;
unsigned int cur_load_maxfreq;
unsigned int samples;
unsigned int window_size;
cpumask_var_t related_cpus;
};
static DEFINE_PER_CPU(struct cpu_load_data, cpuload);
/* Two Endurance Levels for Octa Cores,
* Two for Quad Cores and
* One for Dual
*/
static inline void offline_cpus(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(suspend_cpu_num > NR_CPUS / 2 )
suspend_cpu_num = NR_CPUS / 2;
break;
case 2:
if( NR_CPUS >=4 && suspend_cpu_num > NR_CPUS / 4)
suspend_cpu_num = NR_CPUS / 4;
break;
default:
break;
}
for(cpu = NR_CPUS - 1; cpu > (suspend_cpu_num - 1); cpu--) {
if (cpu_online(cpu))
cpu_down(cpu);
}
pr_info("%s: %d cpus were offlined\n", THUNDERPLUG, (NR_CPUS - suspend_cpu_num));
}
static inline void cpus_online_all(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(resume_cpu_num > (NR_CPUS / 2) - 1 || resume_cpu_num == 1)
resume_cpu_num = ((NR_CPUS / 2) - 1);
break;
case 2:
if( NR_CPUS >= 4 && resume_cpu_num > ((NR_CPUS / 4) - 1))
resume_cpu_num = ((NR_CPUS / 4) - 1);
break;
case 0:
resume_cpu_num = (NR_CPUS - 1);
break;
default:
break;
}
if(DEBUG)
pr_info("%s: resume_cpu_num = %d\n",THUNDERPLUG, resume_cpu_num);
for (cpu = 1; cpu <= resume_cpu_num; cpu++) {
if (cpu_is_offline(cpu))
cpu_up(cpu);
}
pr_info("%s: all cpus were onlined\n", THUNDERPLUG);
}
static void __ref tplug_boost_work_fn(struct work_struct *work)
{
struct cpufreq_policy policy;
int cpu, ret;
for(cpu = 1; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1)
#else
if(tplug_hp_enabled == 1)
#endif
if(cpu_is_offline(cpu))
cpu_up(cpu);
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
continue;
old_policy[cpu] = policy;
policy.min = policy.max;
cpufreq_update_policy(cpu);
}
if(stop_boost == 0)
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(10));
}
static void tplug_input_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
if (type == EV_KEY && code == BTN_TOUCH) {
if(DEBUG)
pr_info("%s : type = %d, code = %d, value = %d\n", THUNDERPLUG, type, code, value);
if(value == 0) {
stop_boost = 1;
if(DEBUG)
pr_info("%s: stopping boost\n", THUNDERPLUG);
}
else {
stop_boost = 0;
if(DEBUG)
pr_info("%s: starting boost\n", THUNDERPLUG);
}
}
#ifdef CONFIG_SCHED_HMP
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#else
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#endif
{
if(DEBUG)
pr_info("%s : touch boost\n", THUNDERPLUG);
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(0));
}
}
static int tplug_input_connect(struct input_handler *handler,
struct input_dev *dev, const struct input_device_id *id)
{
struct input_handle *handle;
int error;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
handle->dev = dev;
handle->handler = handler;
handle->name = "cpufreq";
error = input_register_handle(handle);
if (error)
goto err2;
error = input_open_device(handle);
if (error)
goto err1;
return 0;
err1:
input_unregister_handle(handle);
err2:
kfree(handle);
return error;
}
static void tplug_input_disconnect(struct input_handle *handle)
{
input_close_device(handle);
input_unregister_handle(handle);
kfree(handle);
}
static const struct input_device_id tplug_ids[] = {
{ .driver_info = 1 },
{ },
};
static struct input_handler tplug_input_handler = {
.event = tplug_input_event,
.connect = tplug_input_connect,
.disconnect = tplug_input_disconnect,
.name = "tplug_handler",
.id_table = tplug_ids,
};
static ssize_t thunderplug_suspend_cpus_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", suspend_cpu_num);
}
static ssize_t thunderplug_suspend_cpus_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val < 1 || val > NR_CPUS)
pr_info("%s: suspend cpus off-limits\n", THUNDERPLUG);
else
suspend_cpu_num = val;
return count;
}
static ssize_t thunderplug_endurance_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", endurance_level);
}
static ssize_t __ref thunderplug_endurance_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(tplug_hp_style == 1) {
switch(val) {
case 0:
case 1:
case 2:
if(endurance_level!=val &&
!(endurance_level > 1 && NR_CPUS < 4)) {
endurance_level = val;
offline_cpus();
cpus_online_all();
}
break;
default:
pr_info("%s: invalid endurance level\n", THUNDERPLUG);
break;
}
}
else
pr_info("%s: per-core hotplug style is disabled, ignoring endurance mode values\n", THUNDERPLUG);
return count;
}
static ssize_t thunderplug_sampling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", sampling_time);
}
static ssize_t __ref thunderplug_sampling_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > MIN_SAMLING_MS)
sampling_time = val;
return count;
}
static ssize_t thunderplug_tb_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", touch_boost_enabled);
}
static ssize_t __ref thunderplug_tb_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
switch(val)
{
case 0:
case 1:
touch_boost_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
return count;
}
static ssize_t thunderplug_load_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", load_threshold);
}
static ssize_t __ref thunderplug_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > 10)
load_threshold = val;
return count;
}
static unsigned int get_curr_load(unsigned int cpu)
{
int ret;
unsigned int idle_time, wall_time;
unsigned int cur_load;
u64 cur_wall_time, cur_idle_time;
struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
struct cpufreq_policy policy;
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
return -EINVAL;
cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, 0);
wall_time = (unsigned int) (cur_wall_time - pcpu->prev_cpu_wall);
pcpu->prev_cpu_wall = cur_wall_time;
idle_time = (unsigned int) (cur_idle_time - pcpu->prev_cpu_idle);
pcpu->prev_cpu_idle = cur_idle_time;
if (unlikely(!wall_time || wall_time < idle_time))
return 0;
cur_load = 100 * (wall_time - idle_time) / wall_time;
return cur_load;
}
static void thunderplug_suspend(void)
{
offline_cpus();
pr_info("%s: suspend\n", THUNDERPLUG);
}
static void __ref thunderplug_resume(void)
{
cpus_online_all();
pr_info("%s: resume\n", THUNDERPLUG);
}
static void __cpuinit tplug_resume_work_fn(struct work_struct *work)
{
thunderplug_resume();
}
static void __cpuinit tplug_work_fn(struct work_struct *work)
{
int i;
unsigned int load[8], avg_load[8];
switch(endurance_level)
{
case 0:
core_limit = NR_CPUS;
break;
case 1:
core_limit = NR_CPUS / 2;
break;
case 2:
core_limit = NR_CPUS / 4;
break;
default:
core_limit = NR_CPUS;
break;
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i))
load[i] = get_curr_load(i);
else
load[i] = 0;
avg_load[i] = ((int) load[i] + (int) last_load[i]) / 2;
last_load[i] = load[i];
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i) && avg_load[i] > load_threshold && cpu_is_offline(i+1))
{
if(DEBUG)
pr_info("%s : bringing back cpu%d\n", THUNDERPLUG,i);
if(!((i+1) > 7)) {
last_time[i+1] = ktime_to_ms(ktime_get());
cpu_up(i+1);
}
}
else if(cpu_online(i) && avg_load[i] < load_threshold && cpu_online(i+1))
{
if(DEBUG)
pr_info("%s : offlining cpu%d\n", THUNDERPLUG,i);
if(!(i+1)==0) {
now[i+1] = ktime_to_ms(ktime_get());
if((now[i+1] - last_time[i+1]) > MIN_CPU_UP_TIME)
cpu_down(i+1);
}
}
}
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1 && !isSuspended)
#else
if(tplug_hp_enabled != 0 && !isSuspended)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else {
if(!isSuspended)
cpus_online_all();
else
thunderplug_suspend();
}
}
static int lcd_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
switch (event) {
case LCD_EVENT_ON_START:
isSuspended = false;
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style==1)
#else
if(tplug_hp_enabled)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else
queue_delayed_work_on(0, tplug_resume_wq, &tplug_resume_work,
msecs_to_jiffies(10));
pr_info("thunderplug : resume called\n");
break;
case LCD_EVENT_ON_END:
break;
case LCD_EVENT_OFF_START:
break;
case LCD_EVENT_OFF_END:
isSuspended = true;
pr_info("thunderplug : suspend called\n");
break;
default:
break;
}
return 0;
}
/* Thunderplug load balancer */
#ifdef CONFIG_SCHED_HMP
static void set_sched_profile(int mode) {
switch(mode) {
case 1:
/* Balanced */
sched_set_boost(DISABLED);
break;
case 2:
/* Turbo */
sched_set_boost(ENABLED);
break;
default:
pr_info("%s: Invalid mode\n", THUNDERPLUG);
break;
}
}
static ssize_t thunderplug_sched_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_sched_mode);
}
static ssize_t __ref thunderplug_sched_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
set_sched_profile(val);
tplug_sched_mode = val;
return count;
}
static ssize_t thunderplug_hp_style_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_style);
}
static ssize_t __ref thunderplug_hp_style_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val, last_val;
sscanf(buf, "%d", &val);
last_val = tplug_hp_style;
switch(val)
{
case HOTPLUG_PERCORE:
case HOTPLUG_SCHED:
tplug_hp_style = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_style == HOTPLUG_PERCORE && tplug_hp_style != last_val) {
pr_info("%s: Switching to Per-core hotplug model\n", THUNDERPLUG);
sched_set_boost(DISABLED);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
}
else if(tplug_hp_style==2) {
pr_info("%s: Switching to sched based hotplug model\n", THUNDERPLUG);
set_sched_profile(tplug_sched_mode);
}
return count;
}
static struct kobj_attribute thunderplug_hp_style_attribute =
__ATTR(hotplug_style,
0666,
thunderplug_hp_style_show, thunderplug_hp_style_store);
static struct kobj_attribute thunderplug_mode_attribute =
__ATTR(sched_mode,
0666,
thunderplug_sched_mode_show, thunderplug_sched_mode_store);
#else
static ssize_t thunderplug_hp_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_enabled);
}
static ssize_t __ref thunderplug_hp_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
int last_val = tplug_hp_enabled;
switch(val)
{
case 0:
case 1:
tplug_hp_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_enabled == 1 && tplug_hp_enabled != last_val)
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
return count;
}
static struct kobj_attribute thunderplug_hp_enabled_attribute =
__ATTR(hotplug_enabled,
0666,
thunderplug_hp_enabled_show, thunderplug_hp_enabled_store);
#endif
static ssize_t thunderplug_ver_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "ThunderPlug %u.%u", DRIVER_VERSION, DRIVER_SUBVER);
}
static struct kobj_attribute thunderplug_ver_attribute =
__ATTR(version,
0444,
thunderplug_ver_show, NULL);
static struct kobj_attribute thunderplug_suspend_cpus_attribute =
__ATTR(suspend_cpus,
0666,
thunderplug_suspend_cpus_show, thunderplug_suspend_cpus_store);
static struct kobj_attribute thunderplug_endurance_attribute =
__ATTR(endurance_level,
0666,
thunderplug_endurance_show, thunderplug_endurance_store);
static struct kobj_attribute thunderplug_sampling_attribute =
__ATTR(sampling_rate,
0666,
thunderplug_sampling_show, thunderplug_sampling_store);
static struct kobj_attribute thunderplug_load_attribute =
__ATTR(load_threshold,
0666,
thunderplug_load_show, thunderplug_load_store);
static struct kobj_attribute thunderplug_tb_enabled_attribute =
__ATTR(touch_boost,
0666,
thunderplug_tb_enabled_show, thunderplug_tb_enabled_store);
static struct attribute *thunderplug_attrs[] =
{
&thunderplug_ver_attribute.attr,
&thunderplug_suspend_cpus_attribute.attr,
&thunderplug_endurance_attribute.attr,
&thunderplug_sampling_attribute.attr,
&thunderplug_load_attribute.attr,
#ifdef CONFIG_SCHED_HMP
&thunderplug_mode_attribute.attr,
&thunderplug_hp_style_attribute.attr,
#else
&thunderplug_hp_enabled_attribute.attr,
#endif
&thunderplug_tb_enabled_attribute.attr,
NULL,
};
static struct attribute_group thunderplug_attr_group =
{
.attrs = thunderplug_attrs,
};
static struct kobject *thunderplug_kobj;
static int __init thunderplug_init(void)
{
int ret = 0;
int sysfs_result;
printk(KERN_DEBUG "[%s]\n",__func__);
thunderplug_kobj = kobject_create_and_add("thunderplug", kernel_kobj);
if (!thunderplug_kobj) {
pr_err("%s Interface create failed!\n",
__FUNCTION__);
return -ENOMEM;
}
sysfs_result = sysfs_create_group(thunderplug_kobj, &thunderplug_attr_group);
if (sysfs_result) {
pr_info("%s sysfs create failed!\n", __FUNCTION__);
kobject_put(thunderplug_kobj);
}
lcd_worker.notifier_call = lcd_notifier_callback;
lcd_register_client(&lcd_worker);
pr_info("%s : registering input boost", THUNDERPLUG);
ret = input_register_handler(&tplug_input_handler);
if (ret) {
pr_err("%s: Failed to register input handler: %d\n",
THUNDERPLUG, ret);
}
tplug_wq = alloc_workqueue("tplug",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_resume_wq = alloc_workqueue("tplug_resume",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_boost_wq = alloc_workqueue("tplug_boost",
WQ_HIGHPRI | WQ_UNBOUND, 1);
INIT_DELAYED_WORK(&tplug_work, tplug_work_fn);
INIT_DELAYED_WORK(&tplug_resume_work, tplug_resume_work_fn);
INIT_DELAYED_WORK(&tplug_boost, tplug_boost_work_fn);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(10));
pr_info("%s: init\n", THUNDERPLUG);
return ret;
}
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Varun Chitre <[email protected]>");
MODULE_DESCRIPTION("Hotplug driver for ARM SoCs");
late_initcall(thunderplug_init);
Here is my error.
Code:
CC arch/arm/mach-msm/thunderplug.o
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_endurance_store':
arch/arm/mach-msm/thunderplug.c:283:5: error: 'tplug_hp_style' undeclared (first use in this function)
if(tplug_hp_style == 1) {
^
arch/arm/mach-msm/thunderplug.c:283:5: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_hp_enabled_store':
arch/arm/mach-msm/thunderplug.c:598:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
error, forbidden warning: thunderplug.c:598
make[1]: *** [arch/arm/mach-msm/thunderplug.o] Error 1
make[1]: *** Waiting for unfinished jobs...
Any help would be appreciated
apophis9283 said:
I am trying to add Thundeplug to my hotplug. Heres the code and error.
Code:
/* Copyright (c) 2015, Varun Chitre <[email protected]>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* A simple hotplugging driver.
* Compatible from dual core CPUs to Octa Core CPUs
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/lcd_notify.h>
#include <linux/cpufreq.h>
#include "thunderplug.h"
#define DEBUG 0
#define THUNDERPLUG "thunderplug"
#define DRIVER_VERSION 5
#define DRIVER_SUBVER 0
#define DEFAULT_CPU_LOAD_THRESHOLD (65)
#define MIN_CPU_LOAD_THRESHOLD (10)
#define HOTPLUG_ENABLED (0)
#define DEFAULT_HOTPLUG_STYLE HOTPLUG_SCHED
#define DEFAULT_SCHED_MODE BALANCED
#define DEF_SAMPLING_MS (500)
#define MIN_SAMLING_MS (50)
#define MIN_CPU_UP_TIME (750)
#define TOUCH_BOOST_ENABLED (0)
static bool isSuspended = false;
struct notifier_block lcd_worker;
static int suspend_cpu_num = 2, resume_cpu_num = (NR_CPUS -1);
static int endurance_level = 0;
static int core_limit = NR_CPUS;
static int now[8], last_time[8];
static int sampling_time = DEF_SAMPLING_MS;
static int load_threshold = DEFAULT_CPU_LOAD_THRESHOLD;
static int stop_boost = 0;
struct cpufreq_policy old_policy[NR_CPUS];
#ifdef CONFIG_SCHED_HMP
static int tplug_hp_style = DEFAULT_HOTPLUG_STYLE;
#else
static int tplug_hp_enabled = HOTPLUG_ENABLED;
#endif
static int tplug_sched_mode = DEFAULT_SCHED_MODE;
static int touch_boost_enabled = TOUCH_BOOST_ENABLED;
static struct workqueue_struct *tplug_wq;
static struct delayed_work tplug_work;
static struct workqueue_struct *tplug_boost_wq;
static struct delayed_work tplug_boost;
static struct workqueue_struct *tplug_resume_wq;
static struct delayed_work tplug_resume_work;
static unsigned int last_load[8] = { 0 };
struct cpu_load_data {
u64 prev_cpu_idle;
u64 prev_cpu_wall;
unsigned int avg_load_maxfreq;
unsigned int cur_load_maxfreq;
unsigned int samples;
unsigned int window_size;
cpumask_var_t related_cpus;
};
static DEFINE_PER_CPU(struct cpu_load_data, cpuload);
/* Two Endurance Levels for Octa Cores,
* Two for Quad Cores and
* One for Dual
*/
static inline void offline_cpus(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(suspend_cpu_num > NR_CPUS / 2 )
suspend_cpu_num = NR_CPUS / 2;
break;
case 2:
if( NR_CPUS >=4 && suspend_cpu_num > NR_CPUS / 4)
suspend_cpu_num = NR_CPUS / 4;
break;
default:
break;
}
for(cpu = NR_CPUS - 1; cpu > (suspend_cpu_num - 1); cpu--) {
if (cpu_online(cpu))
cpu_down(cpu);
}
pr_info("%s: %d cpus were offlined\n", THUNDERPLUG, (NR_CPUS - suspend_cpu_num));
}
static inline void cpus_online_all(void)
{
unsigned int cpu;
switch(endurance_level) {
case 1:
if(resume_cpu_num > (NR_CPUS / 2) - 1 || resume_cpu_num == 1)
resume_cpu_num = ((NR_CPUS / 2) - 1);
break;
case 2:
if( NR_CPUS >= 4 && resume_cpu_num > ((NR_CPUS / 4) - 1))
resume_cpu_num = ((NR_CPUS / 4) - 1);
break;
case 0:
resume_cpu_num = (NR_CPUS - 1);
break;
default:
break;
}
if(DEBUG)
pr_info("%s: resume_cpu_num = %d\n",THUNDERPLUG, resume_cpu_num);
for (cpu = 1; cpu <= resume_cpu_num; cpu++) {
if (cpu_is_offline(cpu))
cpu_up(cpu);
}
pr_info("%s: all cpus were onlined\n", THUNDERPLUG);
}
static void __ref tplug_boost_work_fn(struct work_struct *work)
{
struct cpufreq_policy policy;
int cpu, ret;
for(cpu = 1; cpu < NR_CPUS; cpu++) {
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1)
#else
if(tplug_hp_enabled == 1)
#endif
if(cpu_is_offline(cpu))
cpu_up(cpu);
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
continue;
old_policy[cpu] = policy;
policy.min = policy.max;
cpufreq_update_policy(cpu);
}
if(stop_boost == 0)
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(10));
}
static void tplug_input_event(struct input_handle *handle, unsigned int type,
unsigned int code, int value)
{
if (type == EV_KEY && code == BTN_TOUCH) {
if(DEBUG)
pr_info("%s : type = %d, code = %d, value = %d\n", THUNDERPLUG, type, code, value);
if(value == 0) {
stop_boost = 1;
if(DEBUG)
pr_info("%s: stopping boost\n", THUNDERPLUG);
}
else {
stop_boost = 0;
if(DEBUG)
pr_info("%s: starting boost\n", THUNDERPLUG);
}
}
#ifdef CONFIG_SCHED_HMP
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#else
if ((type == EV_KEY) && (code == BTN_TOUCH) && (value == 1)
&& touch_boost_enabled == 1)
#endif
{
if(DEBUG)
pr_info("%s : touch boost\n", THUNDERPLUG);
queue_delayed_work_on(0, tplug_boost_wq, &tplug_boost,
msecs_to_jiffies(0));
}
}
static int tplug_input_connect(struct input_handler *handler,
struct input_dev *dev, const struct input_device_id *id)
{
struct input_handle *handle;
int error;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
handle->dev = dev;
handle->handler = handler;
handle->name = "cpufreq";
error = input_register_handle(handle);
if (error)
goto err2;
error = input_open_device(handle);
if (error)
goto err1;
return 0;
err1:
input_unregister_handle(handle);
err2:
kfree(handle);
return error;
}
static void tplug_input_disconnect(struct input_handle *handle)
{
input_close_device(handle);
input_unregister_handle(handle);
kfree(handle);
}
static const struct input_device_id tplug_ids[] = {
{ .driver_info = 1 },
{ },
};
static struct input_handler tplug_input_handler = {
.event = tplug_input_event,
.connect = tplug_input_connect,
.disconnect = tplug_input_disconnect,
.name = "tplug_handler",
.id_table = tplug_ids,
};
static ssize_t thunderplug_suspend_cpus_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", suspend_cpu_num);
}
static ssize_t thunderplug_suspend_cpus_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val < 1 || val > NR_CPUS)
pr_info("%s: suspend cpus off-limits\n", THUNDERPLUG);
else
suspend_cpu_num = val;
return count;
}
static ssize_t thunderplug_endurance_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", endurance_level);
}
static ssize_t __ref thunderplug_endurance_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(tplug_hp_style == 1) {
switch(val) {
case 0:
case 1:
case 2:
if(endurance_level!=val &&
!(endurance_level > 1 && NR_CPUS < 4)) {
endurance_level = val;
offline_cpus();
cpus_online_all();
}
break;
default:
pr_info("%s: invalid endurance level\n", THUNDERPLUG);
break;
}
}
else
pr_info("%s: per-core hotplug style is disabled, ignoring endurance mode values\n", THUNDERPLUG);
return count;
}
static ssize_t thunderplug_sampling_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", sampling_time);
}
static ssize_t __ref thunderplug_sampling_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > MIN_SAMLING_MS)
sampling_time = val;
return count;
}
static ssize_t thunderplug_tb_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", touch_boost_enabled);
}
static ssize_t __ref thunderplug_tb_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
switch(val)
{
case 0:
case 1:
touch_boost_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
return count;
}
static ssize_t thunderplug_load_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", load_threshold);
}
static ssize_t __ref thunderplug_load_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
if(val > 10)
load_threshold = val;
return count;
}
static unsigned int get_curr_load(unsigned int cpu)
{
int ret;
unsigned int idle_time, wall_time;
unsigned int cur_load;
u64 cur_wall_time, cur_idle_time;
struct cpu_load_data *pcpu = &per_cpu(cpuload, cpu);
struct cpufreq_policy policy;
ret = cpufreq_get_policy(&policy, cpu);
if (ret)
return -EINVAL;
cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, 0);
wall_time = (unsigned int) (cur_wall_time - pcpu->prev_cpu_wall);
pcpu->prev_cpu_wall = cur_wall_time;
idle_time = (unsigned int) (cur_idle_time - pcpu->prev_cpu_idle);
pcpu->prev_cpu_idle = cur_idle_time;
if (unlikely(!wall_time || wall_time < idle_time))
return 0;
cur_load = 100 * (wall_time - idle_time) / wall_time;
return cur_load;
}
static void thunderplug_suspend(void)
{
offline_cpus();
pr_info("%s: suspend\n", THUNDERPLUG);
}
static void __ref thunderplug_resume(void)
{
cpus_online_all();
pr_info("%s: resume\n", THUNDERPLUG);
}
static void __cpuinit tplug_resume_work_fn(struct work_struct *work)
{
thunderplug_resume();
}
static void __cpuinit tplug_work_fn(struct work_struct *work)
{
int i;
unsigned int load[8], avg_load[8];
switch(endurance_level)
{
case 0:
core_limit = NR_CPUS;
break;
case 1:
core_limit = NR_CPUS / 2;
break;
case 2:
core_limit = NR_CPUS / 4;
break;
default:
core_limit = NR_CPUS;
break;
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i))
load[i] = get_curr_load(i);
else
load[i] = 0;
avg_load[i] = ((int) load[i] + (int) last_load[i]) / 2;
last_load[i] = load[i];
}
for(i = 0 ; i < core_limit; i++)
{
if(cpu_online(i) && avg_load[i] > load_threshold && cpu_is_offline(i+1))
{
if(DEBUG)
pr_info("%s : bringing back cpu%d\n", THUNDERPLUG,i);
if(!((i+1) > 7)) {
last_time[i+1] = ktime_to_ms(ktime_get());
cpu_up(i+1);
}
}
else if(cpu_online(i) && avg_load[i] < load_threshold && cpu_online(i+1))
{
if(DEBUG)
pr_info("%s : offlining cpu%d\n", THUNDERPLUG,i);
if(!(i+1)==0) {
now[i+1] = ktime_to_ms(ktime_get());
if((now[i+1] - last_time[i+1]) > MIN_CPU_UP_TIME)
cpu_down(i+1);
}
}
}
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style == 1 && !isSuspended)
#else
if(tplug_hp_enabled != 0 && !isSuspended)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else {
if(!isSuspended)
cpus_online_all();
else
thunderplug_suspend();
}
}
static int lcd_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
switch (event) {
case LCD_EVENT_ON_START:
isSuspended = false;
#ifdef CONFIG_SCHED_HMP
if(tplug_hp_style==1)
#else
if(tplug_hp_enabled)
#endif
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
else
queue_delayed_work_on(0, tplug_resume_wq, &tplug_resume_work,
msecs_to_jiffies(10));
pr_info("thunderplug : resume called\n");
break;
case LCD_EVENT_ON_END:
break;
case LCD_EVENT_OFF_START:
break;
case LCD_EVENT_OFF_END:
isSuspended = true;
pr_info("thunderplug : suspend called\n");
break;
default:
break;
}
return 0;
}
/* Thunderplug load balancer */
#ifdef CONFIG_SCHED_HMP
static void set_sched_profile(int mode) {
switch(mode) {
case 1:
/* Balanced */
sched_set_boost(DISABLED);
break;
case 2:
/* Turbo */
sched_set_boost(ENABLED);
break;
default:
pr_info("%s: Invalid mode\n", THUNDERPLUG);
break;
}
}
static ssize_t thunderplug_sched_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_sched_mode);
}
static ssize_t __ref thunderplug_sched_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
set_sched_profile(val);
tplug_sched_mode = val;
return count;
}
static ssize_t thunderplug_hp_style_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_style);
}
static ssize_t __ref thunderplug_hp_style_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val, last_val;
sscanf(buf, "%d", &val);
last_val = tplug_hp_style;
switch(val)
{
case HOTPLUG_PERCORE:
case HOTPLUG_SCHED:
tplug_hp_style = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_style == HOTPLUG_PERCORE && tplug_hp_style != last_val) {
pr_info("%s: Switching to Per-core hotplug model\n", THUNDERPLUG);
sched_set_boost(DISABLED);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
}
else if(tplug_hp_style==2) {
pr_info("%s: Switching to sched based hotplug model\n", THUNDERPLUG);
set_sched_profile(tplug_sched_mode);
}
return count;
}
static struct kobj_attribute thunderplug_hp_style_attribute =
__ATTR(hotplug_style,
0666,
thunderplug_hp_style_show, thunderplug_hp_style_store);
static struct kobj_attribute thunderplug_mode_attribute =
__ATTR(sched_mode,
0666,
thunderplug_sched_mode_show, thunderplug_sched_mode_store);
#else
static ssize_t thunderplug_hp_enabled_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%d", tplug_hp_enabled);
}
static ssize_t __ref thunderplug_hp_enabled_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
int val;
sscanf(buf, "%d", &val);
int last_val = tplug_hp_enabled;
switch(val)
{
case 0:
case 1:
tplug_hp_enabled = val;
break;
default:
pr_info("%s : invalid choice\n", THUNDERPLUG);
break;
}
if(tplug_hp_enabled == 1 && tplug_hp_enabled != last_val)
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(sampling_time));
return count;
}
static struct kobj_attribute thunderplug_hp_enabled_attribute =
__ATTR(hotplug_enabled,
0666,
thunderplug_hp_enabled_show, thunderplug_hp_enabled_store);
#endif
static ssize_t thunderplug_ver_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "ThunderPlug %u.%u", DRIVER_VERSION, DRIVER_SUBVER);
}
static struct kobj_attribute thunderplug_ver_attribute =
__ATTR(version,
0444,
thunderplug_ver_show, NULL);
static struct kobj_attribute thunderplug_suspend_cpus_attribute =
__ATTR(suspend_cpus,
0666,
thunderplug_suspend_cpus_show, thunderplug_suspend_cpus_store);
static struct kobj_attribute thunderplug_endurance_attribute =
__ATTR(endurance_level,
0666,
thunderplug_endurance_show, thunderplug_endurance_store);
static struct kobj_attribute thunderplug_sampling_attribute =
__ATTR(sampling_rate,
0666,
thunderplug_sampling_show, thunderplug_sampling_store);
static struct kobj_attribute thunderplug_load_attribute =
__ATTR(load_threshold,
0666,
thunderplug_load_show, thunderplug_load_store);
static struct kobj_attribute thunderplug_tb_enabled_attribute =
__ATTR(touch_boost,
0666,
thunderplug_tb_enabled_show, thunderplug_tb_enabled_store);
static struct attribute *thunderplug_attrs[] =
{
&thunderplug_ver_attribute.attr,
&thunderplug_suspend_cpus_attribute.attr,
&thunderplug_endurance_attribute.attr,
&thunderplug_sampling_attribute.attr,
&thunderplug_load_attribute.attr,
#ifdef CONFIG_SCHED_HMP
&thunderplug_mode_attribute.attr,
&thunderplug_hp_style_attribute.attr,
#else
&thunderplug_hp_enabled_attribute.attr,
#endif
&thunderplug_tb_enabled_attribute.attr,
NULL,
};
static struct attribute_group thunderplug_attr_group =
{
.attrs = thunderplug_attrs,
};
static struct kobject *thunderplug_kobj;
static int __init thunderplug_init(void)
{
int ret = 0;
int sysfs_result;
printk(KERN_DEBUG "[%s]\n",__func__);
thunderplug_kobj = kobject_create_and_add("thunderplug", kernel_kobj);
if (!thunderplug_kobj) {
pr_err("%s Interface create failed!\n",
__FUNCTION__);
return -ENOMEM;
}
sysfs_result = sysfs_create_group(thunderplug_kobj, &thunderplug_attr_group);
if (sysfs_result) {
pr_info("%s sysfs create failed!\n", __FUNCTION__);
kobject_put(thunderplug_kobj);
}
lcd_worker.notifier_call = lcd_notifier_callback;
lcd_register_client(&lcd_worker);
pr_info("%s : registering input boost", THUNDERPLUG);
ret = input_register_handler(&tplug_input_handler);
if (ret) {
pr_err("%s: Failed to register input handler: %d\n",
THUNDERPLUG, ret);
}
tplug_wq = alloc_workqueue("tplug",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_resume_wq = alloc_workqueue("tplug_resume",
WQ_HIGHPRI | WQ_UNBOUND, 1);
tplug_boost_wq = alloc_workqueue("tplug_boost",
WQ_HIGHPRI | WQ_UNBOUND, 1);
INIT_DELAYED_WORK(&tplug_work, tplug_work_fn);
INIT_DELAYED_WORK(&tplug_resume_work, tplug_resume_work_fn);
INIT_DELAYED_WORK(&tplug_boost, tplug_boost_work_fn);
queue_delayed_work_on(0, tplug_wq, &tplug_work,
msecs_to_jiffies(10));
pr_info("%s: init\n", THUNDERPLUG);
return ret;
}
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Varun Chitre <[email protected]>");
MODULE_DESCRIPTION("Hotplug driver for ARM SoCs");
late_initcall(thunderplug_init);
Here is my error.
Code:
CC arch/arm/mach-msm/thunderplug.o
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_endurance_store':
arch/arm/mach-msm/thunderplug.c:283:5: error: 'tplug_hp_style' undeclared (first use in this function)
if(tplug_hp_style == 1) {
^
arch/arm/mach-msm/thunderplug.c:283:5: note: each undeclared identifier is reported only once for each function it appears in
arch/arm/mach-msm/thunderplug.c: In function 'thunderplug_hp_enabled_store':
arch/arm/mach-msm/thunderplug.c:598:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
error, forbidden warning: thunderplug.c:598
make[1]: *** [arch/arm/mach-msm/thunderplug.o] Error 1
make[1]: *** Waiting for unfinished jobs...
Any help would be appreciated
Click to expand...
Click to collapse
Hard to say without seeing your whole kernel source but it looks like you don't use:
CONFIG_SCHED_HMP
@RenderBroken
See here, thanks for helping
https://github.com/varunchitre15/th...36ca2904495a/arch/arm64/hotplug/thunderplug.c
Looking for the commits now
Doesnt look like I have whats needed. Might take awhile to track all the commits down
Edit: Still not working. Ill keep looking into it
apophis9283 said:
@RenderBroken
See here, thanks for helping
https://github.com/varunchitre15/th...36ca2904495a/arch/arm64/hotplug/thunderplug.c
Looking for the commits now
Doesnt look like I have whats needed. Might take awhile to track all the commits down
Edit: Still not working. Ill keep looking into it
Click to expand...
Click to collapse
No sweat bro.
I am pretty sure the problem is that you are missing all the HMP commits in /kernel/sched and the hotplug driver wasn't coded to work without HMP. (By accident, I think he meant to though)
I have them but there is a large bringup to make it work I have done it with my test branch here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3
Honestly, I don't think it is worth the work.
RenderBroken said:
No sweat bro.
I am pretty sure the problem is that you are missing all the HMP commits in /kernel/sched and the hotplug driver wasn't coded to work without HMP. (By accident, I think he meant to though)
I have them but there is a large bringup to make it work I have done it with my test branch here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3
Honestly, I don't think it is worth the work.
Click to expand...
Click to collapse
I really want to get it working. I have it working but its like v1.0, im trying to get 5.0 to work
apophis9283 said:
I really want to get it working. I have it working but its like v1.0, im trying to get 5.0 to work
Click to expand...
Click to collapse
If you really want it working then you will need to make all the sched commits starting from here: https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=10
to here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=1
RenderBroken said:
If you really want it working then you will need to make all the sched commits starting from here: https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=10
to here:
https://github.com/RenderBroken/SHAMU-kernel/commits/r1-t3?page=1
Click to expand...
Click to collapse
Im just merging that branch into mine
apophis9283 said:
Im just merging that branch into mine
Click to expand...
Click to collapse
you know, the way I merge a massive number of commits in order is by:
1. git fetch the remote source to your local kernel source. This may mean adding the remote first.
2. Now you can create patches from their commits by using: git format-patch
3 So to create a range of patches from a range of commits (they have to be in order) you just:
Code:
git format-patch 8a8e3fff2c84152a7cb3895ff3b98fd6115f2d5a..142bfdc7328dd5290e99216674a2a48e23f645ba
The above is just an example but notice the".." in between the SHA1's. This means "and all commits in between these two commits".
4. So once you have all the patches created in your local source, you can apply them all really easily by running:
Code:
git am *.patch
The above means to apply all patches because all patches end in ".patch"
It will then start applying the patches in order right ontop of your source. If it fails a single commit it will let you fix it, skip it or just abort the whole thing. To fix it I just look for the commit message in the other's kernel source and cherry-pick it like normal. Cherry-picking is not as picky as git am is so most of the time it will apply the commit. If it succeeds, you just run:
Code:
git am --skip
Since you had applied the commit manually so it can skip over doing it.
To me this just keeps history cleaner and can sometimes be a huge time saver when all you want is a range of commits from another's source without merging in their other crap you dont want.
RenderBroken said:
you know, the way I merge a massive number of commits in order is by:
1. git fetch the remote source to your local kernel source. This may mean adding the remote first.
2. Now you can create patches from their commits by using: git format-patch
3 So to create a range of patches from a range of commits (they have to be in order) you just:
Code:
git format-patch 8a8e3fff2c84152a7cb3895ff3b98fd6115f2d5a..142bfdc7328dd5290e99216674a2a48e23f645ba
The above is just an example but notice the".." in between the SHA1's. This means "and all commits in between these two commits".
4. So once you have all the patches created in your local source, you can apply them all really easily by running:
Code:
git am *.patch
The above means to apply all patches because all patches end in ".patch"
It will then start applying the patches in order right ontop of your source. If it fails a single commit it will let you fix it, skip it or just abort the whole thing. To fix it I just look for the commit message in the other's kernel source and cherry-pick it like normal. Cherry-picking is not as picky as git am is so most of the time it will apply the commit. If it succeeds, you just run:
Code:
git am --skip
Since you had applied the commit manually so it can skip over doing it.
To me this just keeps history cleaner and can sometimes be a huge time saver when all you want is a range of commits from another's source without merging in their other crap you dont want.
Click to expand...
Click to collapse
sweet
apophis9283 said:
sweet
Click to expand...
Click to collapse
Yea, neobuddy89 taught me that trick a long time ago. I use it ALL the time when rebasing and such.
RenderBroken said:
Yea, neobuddy89 taught me that trick a long time ago. I use it ALL the time when rebasing and such.
Click to expand...
Click to collapse
Working on it now. Still gonna take a bit
Decided just to cp it all. It may take most of the night but...
apophis9283 said:
Decided just to cp it all. It may take most of the night but...
Click to expand...
Click to collapse
It takes time to Learn properly. I know it took me quite a bit of time at least.
RenderBroken said:
It takes time to Learn properly. I know it took me quite a bit of time at least.
Click to expand...
Click to collapse
Yeah, ive actually got quite far
Just merged all those. Damn that sucked
@RenderBroken
I get this error, not sure if i missed anything
kernel/sched/core.c: In function 'sd_init_CPU':
kernel/sched/core.c:8448:8: error: 'SD_CPU_INIT' undeclared (first use in this function)
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8454:1: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(CPU)
^
kernel/sched/core.c:8448:8: note: each undeclared identifier is reported only once for each function it appears in
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8454:1: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(CPU)
^
kernel/sched/core.c: In function 'sd_init_MC':
kernel/sched/core.c:8448:8: error: 'SD_MC_INIT' undeclared (first use in this function)
*sd = SD_##type##_INIT; \
^
kernel/sched/core.c:8459:2: note: in expansion of macro 'SD_INIT_FUNC'
SD_INIT_FUNC(MC)
^
I think topology is what im missing for that error. Just not sure
apophis9283 said:
I think topology is what im missing for that error. Just not sure
Click to expand...
Click to collapse
yea, did you remove the CONFIG_SCHED_MC stuff from your source?
RenderBroken said:
yea, did you remove the CONFIG_SCHED_MC stuff from your source?
Click to expand...
Click to collapse
Dont think so. Ive been trying all day to get it to compile
@RenderBroken
What would I be looking for?
I looked at my topology.h file. The parts that errored are in it
Probably just gonna revert all that. I cant get it working so its not worth the time
@RenderBroken
I decided to take a different route.
drivers/soc/qcom/thunderplug.c:281:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
I need to change it to c99 but dont know what to edit