diff options
Diffstat (limited to 'target/linux/xburst/files-2.6.32/drivers')
14 files changed, 0 insertions, 8780 deletions
diff --git a/target/linux/xburst/files-2.6.32/drivers/char/defkeymap.c_shipped b/target/linux/xburst/files-2.6.32/drivers/char/defkeymap.c_shipped deleted file mode 100644 index fca8d595a8..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/char/defkeymap.c_shipped +++ /dev/null @@ -1,422 +0,0 @@ -/* Do not edit this file! It was automatically generated by */ -/* loadkeys --mktable defkeymap.map > defkeymap.c */ - -#include <linux/types.h> -#include <linux/keyboard.h> -#include <linux/kd.h> - -u_short plain_map[NR_KEYS] = { - 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, - 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf706, 0xfb61, 0xfb73, - 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, - 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf701, 0xf30c, - 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short shift_map[NR_KEYS] = { - 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, - 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, - 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, - 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf706, 0xfb41, 0xfb53, - 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, - 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, - 0xfb42, 0xfb4e, 0xfb4d, 0xf03b, 0xf03a, 0xf03f, 0xf701, 0xf30c, - 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, - 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short altgr_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, - 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf07e, 0xf008, 0xf200, - 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, 0xf026, 0xf02a, - 0xf028, 0xf029, 0xf200, 0xf07e, 0xf201, 0xf706, 0xf0b0, 0xf0a8, - 0xf0a4, 0xf02d, 0xf05f, 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xf039, 0xf030, 0xf916, 0xfb76, - 0xf915, 0xf03c, 0xf03e, 0xf027, 0xf022, 0xf200, 0xf701, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, - 0xf036, 0xf037, 0xf038, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, - 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, - 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, - 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short ctrl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, - 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, - 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, - 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf706, 0xf001, 0xf013, - 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, - 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf701, 0xf30c, - 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short shift_ctrl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, - 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, - 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf706, 0xf001, 0xf013, - 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, - 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short alt_map[NR_KEYS] = { - 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, - 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, - 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, - 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf706, 0xf861, 0xf873, - 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, - 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, - 0xf862, 0xf86e, 0xf86d, 0xf200, 0xf200, 0xf82f, 0xf701, 0xf30c, - 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, - 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907, - 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, - 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, - 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short ctrl_alt_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, - 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf706, 0xf801, 0xf813, - 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, - 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf701, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, - 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, - 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -static u_short ctl_map[NR_KEYS] = { - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf033, 0xf200, 0xf200, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xf037, 0xf038, - 0xf039, 0xfb70, 0xf200, 0xf200, 0xf201, 0xf706, 0xfb61, 0xfb73, - 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xf034, 0xf035, 0xf036, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xf031, 0xf032, 0xf200, 0xf200, 0xf030, 0xf701, 0xf30c, - 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, - 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, - 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, - 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, -}; - -ushort *key_maps[MAX_NR_KEYMAPS] = { - plain_map, shift_map, altgr_map, 0, - ctrl_map, shift_ctrl_map, 0, 0, - alt_map, 0, 0, 0, - ctrl_alt_map, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - ctl_map, 0 -}; - -unsigned int keymap_count = 8; - -/* - * Philosophy: most people do not define more strings, but they who do - * often want quite a lot of string space. So, we statically allocate - * the default and allocate dynamically in chunks of 512 bytes. - */ - -char func_buf[] = { - '\033', '[', '[', 'A', 0, - '\033', '[', '[', 'B', 0, - '\033', '[', '[', 'C', 0, - '\033', '[', '[', 'D', 0, - '\033', '[', '[', 'E', 0, - '\033', '[', '1', '7', '~', 0, - '\033', '[', '1', '8', '~', 0, - '\033', '[', '1', '9', '~', 0, - '\033', '[', '2', '0', '~', 0, - '\033', '[', '2', '1', '~', 0, - '\033', '[', '2', '3', '~', 0, - '\033', '[', '2', '4', '~', 0, - '\033', '[', '2', '5', '~', 0, - '\033', '[', '2', '6', '~', 0, - '\033', '[', '2', '8', '~', 0, - '\033', '[', '2', '9', '~', 0, - '\033', '[', '3', '1', '~', 0, - '\033', '[', '3', '2', '~', 0, - '\033', '[', '3', '3', '~', 0, - '\033', '[', '3', '4', '~', 0, - '\033', '[', '1', '~', 0, - '\033', '[', '2', '~', 0, - '\033', '[', '3', '~', 0, - '\033', '[', '4', '~', 0, - '\033', '[', '5', '~', 0, - '\033', '[', '6', '~', 0, - '\033', '[', 'M', 0, - '\033', '[', 'P', 0, -}; - -char *funcbufptr = func_buf; -int funcbufsize = sizeof(func_buf); -int funcbufleft = 0; /* space left */ - -char *func_table[MAX_NR_FUNC] = { - func_buf + 0, - func_buf + 5, - func_buf + 10, - func_buf + 15, - func_buf + 20, - func_buf + 25, - func_buf + 31, - func_buf + 37, - func_buf + 43, - func_buf + 49, - func_buf + 55, - func_buf + 61, - func_buf + 67, - func_buf + 73, - func_buf + 79, - func_buf + 85, - func_buf + 91, - func_buf + 97, - func_buf + 103, - func_buf + 109, - func_buf + 115, - func_buf + 120, - func_buf + 125, - func_buf + 130, - func_buf + 135, - func_buf + 140, - func_buf + 145, - 0, - 0, - func_buf + 149, - 0, -}; - -struct kbdiacr accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, -}; - -unsigned int accent_table_size = 68; diff --git a/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n516-lpc.c b/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n516-lpc.c deleted file mode 100644 index 20357ee2eb..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n516-lpc.c +++ /dev/null @@ -1,477 +0,0 @@ -#include <linux/module.h> -#include <linux/version.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/sched.h> -#include <linux/pm.h> -#include <linux/sysctl.h> -#include <linux/proc_fs.h> -#include <linux/delay.h> -#include <linux/platform_device.h> -#include <linux/input.h> -#include <linux/power_supply.h> -#include <linux/suspend.h> - -#include <linux/i2c.h> - -#include <asm/mach-jz4740/irq.h> -#include <asm/mach-jz4740/gpio.h> -#include <asm/mach-jz4740/board-n516.h> - -static int batt_level=0; -module_param(batt_level, int, 0); - -struct n516_lpc_chip { - struct i2c_client *i2c_client; - struct input_dev *input; - unsigned int battery_level; - unsigned int suspending:1, can_sleep:1; -}; - -static struct n516_lpc_chip *the_lpc; - -struct i2c_device_id n516_lpc_i2c_ids[] = { - {"LPC524", 0}, - {}, -}; - -MODULE_DEVICE_TABLE(i2c, n516_lpc_i2c_ids); - -static const unsigned short normal_i2c[] = {0x54, I2C_CLIENT_END}; - -static const unsigned int n516_lpc_keymap[] = { - [0x01] = KEY_4, - [0x02] = KEY_3, - [0x03] = KEY_2, - [0x04] = KEY_1, - [0x05] = KEY_0, - [0x07] = KEY_9, - [0x08] = KEY_8, - [0x09] = KEY_7, - [0x0a] = KEY_6, - [0x0b] = KEY_5, - [0x0d] = KEY_PLAYPAUSE, - [0x0e] = KEY_MENU, - [0x0f] = KEY_SEARCH, - [0x10] = KEY_DIRECTION, - [0x11] = KEY_SPACE, - [0x13] = KEY_ENTER, - [0x14] = KEY_UP, - [0x15] = KEY_DOWN, - [0x16] = KEY_RIGHT, - [0x17] = KEY_LEFT, - [0x19] = KEY_PAGEDOWN, - [0x1a] = KEY_PAGEUP, - [0x1c] = KEY_POWER, - [0x1d] = KEY_ESC, - [0x1e] = KEY_SLEEP, - [0x1f] = KEY_WAKEUP, -}; - -static const unsigned int batt_charge[] = {0, 7, 20, 45, 65, 80, 100}; -#define MAX_BAT_LEVEL 6 - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(n516_lpc); - -static inline int n516_bat_charging(void) -{ - return !gpio_get_value(GPIO_CHARG_STAT_N); -} - -static int n516_bat_get_status(struct power_supply *b) -{ - if (power_supply_am_i_supplied(b)) { - if (n516_bat_charging()) - return POWER_SUPPLY_STATUS_CHARGING; - else - return POWER_SUPPLY_STATUS_FULL; - } else { - return POWER_SUPPLY_STATUS_DISCHARGING; - } -} - -static int n516_bat_get_charge(struct power_supply *b) -{ - return batt_charge[the_lpc->battery_level]; -} - -static int n516_bat_get_property(struct power_supply *b, - enum power_supply_property psp, - union power_supply_propval *val) -{ - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = n516_bat_get_status(b); - break; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - val->intval = 100; - break; - case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN: - val->intval = 0; - break; - case POWER_SUPPLY_PROP_CHARGE_NOW: - val->intval = n516_bat_get_charge(b); - break; - default: - return -EINVAL; - } - return 0; -} - -static void n516_bat_power_changed(struct power_supply *p) -{ - if (power_supply_am_i_supplied(p) && !n516_bat_charging()) - the_lpc->battery_level = MAX_BAT_LEVEL; - - power_supply_changed(p); -} - -static enum power_supply_property n516_bat_properties[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN, - POWER_SUPPLY_PROP_CHARGE_NOW, -}; - -static struct power_supply n516_battery = { - .name = "n516-battery", - .get_property = n516_bat_get_property, - .properties = n516_bat_properties, - .num_properties = ARRAY_SIZE(n516_bat_properties), - .external_power_changed = n516_bat_power_changed, -}; - -static irqreturn_t n516_bat_charge_irq(int irq, void *dev) -{ - struct power_supply *psy = dev; - - dev_dbg(psy->dev, "Battery charging IRQ\n"); - - if (power_supply_am_i_supplied(psy) && !n516_bat_charging()) - the_lpc->battery_level = MAX_BAT_LEVEL; - - power_supply_changed(psy); - - return IRQ_HANDLED; -} - -static int n516_lpc_send_message(struct n516_lpc_chip *chip, unsigned char val) -{ - struct i2c_client *client = chip->i2c_client; - struct i2c_msg msg = {client->addr, client->flags, 1, &val}; - int ret = 0; - - ret = i2c_transfer(client->adapter, &msg, 1); - return ret > 0 ? 0 : ret; -} - -static void n516_key_event(struct n516_lpc_chip *chip, unsigned char keycode) -{ - struct i2c_client *client = chip->i2c_client; - bool long_press = false; - - if (keycode & 0x40) { - keycode &= ~0x40; - long_press = true; - } - - dev_dbg(&client->dev, "keycode: 0x%02x, long_press: 0x%02x\n", keycode, (unsigned int)long_press); - - if (keycode >= ARRAY_SIZE(n516_lpc_keymap) || n516_lpc_keymap[keycode] == 0) - return; - - if (long_press) - input_report_key(chip->input, KEY_LEFTALT, 1); - - input_report_key(chip->input, n516_lpc_keymap[keycode], 1); - input_sync(chip->input); - input_report_key(chip->input, n516_lpc_keymap[keycode], 0); - - if (long_press) - input_report_key(chip->input, KEY_LEFTALT, 0); - input_sync(chip->input); -} - -static void n516_battery_event(struct n516_lpc_chip *chip, unsigned char battery_level) -{ - if (battery_level != chip->battery_level) { - chip->battery_level = battery_level; - power_supply_changed(&n516_battery); - } -} - -static irqreturn_t n516_lpc_irq_thread(int irq, void *devid) -{ - struct n516_lpc_chip *chip = (struct n516_lpc_chip*)devid; - int ret; - unsigned char raw_msg; - struct i2c_client *client = chip->i2c_client; - struct i2c_msg msg = {client->addr, client->flags | I2C_M_RD, 1, &raw_msg}; - - if (client->dev.power.status >= DPM_OFF) - return IRQ_HANDLED; - - ret = i2c_transfer(client->adapter, &msg, 1); - if (ret != 1) { - dev_dbg(&client->dev, "I2C error: %d\n", ret); - return IRQ_HANDLED; - } - - dev_dbg(&client->dev, "msg: 0x%02x\n", raw_msg); - - /* Ack wakeup event */ - if ((raw_msg & ~0x40) < ARRAY_SIZE(n516_lpc_keymap)) - n516_key_event(chip, raw_msg); - else if ((raw_msg >= 0x81) && (raw_msg <= 0x87)) - n516_battery_event(chip, raw_msg - 0x81); - else if (raw_msg == 0x7e) - n516_lpc_send_message(chip, 0x00); - else - dev_warn(&client->dev, "Unknown message: %x\n", raw_msg); - - if (chip->suspending) - chip->can_sleep = 0; - - return IRQ_HANDLED; -} - -static void n516_lpc_power_off(void) -{ - struct i2c_client *client = the_lpc->i2c_client; - unsigned char val = 0x01; - struct i2c_msg msg = {client->addr, client->flags, 1, &val}; - - printk("Issue LPC POWEROFF command...\n"); - while (1) - i2c_transfer(client->adapter, &msg, 1); -} - -static int n516_lpc_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) -{ - return 0; -} - -static int n516_lpc_suspend_notifier(struct notifier_block *nb, - unsigned long event, - void *dummy) -{ - switch(event) { - case PM_SUSPEND_PREPARE: - the_lpc->suspending = 1; - the_lpc->can_sleep = 1; - break; - case PM_POST_SUSPEND: - the_lpc->suspending = 0; - the_lpc->can_sleep = 1; - break; - default: - return NOTIFY_DONE; - } - return NOTIFY_OK; -} - -static struct notifier_block n516_lpc_notif_block = { - .notifier_call = n516_lpc_suspend_notifier, -}; - -static int __devinit n516_lpc_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct n516_lpc_chip *chip; - struct input_dev *input; - int ret = 0; - int i; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - the_lpc = chip; - chip->i2c_client = client; - if ((batt_level > 0) && (batt_level < ARRAY_SIZE(batt_charge))) - chip->battery_level = batt_level; - else - chip->battery_level = 1; - - i2c_set_clientdata(client, chip); - - ret = gpio_request(GPIO_LPC_INT, "LPC interrupt request"); - if (ret) { - dev_err(&client->dev, "Unable to reguest LPC INT GPIO\n"); - goto err_gpio_req_lpcint; - } - - ret = gpio_request(GPIO_CHARG_STAT_N, "LPC charging status"); - if (ret) { - dev_err(&client->dev, "Unable to reguest CHARG STAT GPIO\n"); - goto err_gpio_req_chargstat; - } - - /* Enter normal mode */ - n516_lpc_send_message(chip, 0x2); - - input = input_allocate_device(); - if (!input) { - dev_err(&client->dev, "Unable to allocate input device\n"); - ret = -ENOMEM; - goto err_input_alloc; - } - - chip->input = input; - - __set_bit(EV_KEY, input->evbit); - - for (i = 0; i < ARRAY_SIZE(n516_lpc_keymap); i++) - __set_bit(n516_lpc_keymap[i], input->keybit); - - __set_bit(KEY_LEFTALT, input->keybit); - - input->name = "n516-keys"; - input->phys = "n516-keys/input0"; - input->dev.parent = &client->dev; - input->id.bustype = BUS_I2C; - input->id.vendor = 0x0001; - input->id.product = 0x0001; - input->id.version = 0x0100; - - ret = input_register_device(input); - if (ret < 0) { - dev_err(&client->dev, "Unable to register input device\n"); - goto err_input_register; - } - - ret = power_supply_register(NULL, &n516_battery); - if (ret) { - dev_err(&client->dev, "Unable to register N516 battery\n"); - goto err_bat_reg; - } - - ret = request_threaded_irq(gpio_to_irq(GPIO_LPC_INT), NULL, - n516_lpc_irq_thread, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "lpc", chip); - if (ret) { - dev_err(&client->dev, "request_irq failed: %d\n", ret); - goto err_request_lpc_irq; - } - - ret = request_irq(gpio_to_irq(GPIO_CHARG_STAT_N), n516_bat_charge_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "battery charging", &n516_battery); - if (ret) { - dev_err(&client->dev, "Unable to claim battery charging IRQ\n"); - goto err_request_chrg_irq; - } - - pm_power_off = n516_lpc_power_off; - ret = register_pm_notifier(&n516_lpc_notif_block); - if (ret) { - dev_err(&client->dev, "Unable to register PM notify block\n"); - goto err_reg_pm_notifier; - } - - device_init_wakeup(&client->dev, 1); - - return 0; - - unregister_pm_notifier(&n516_lpc_notif_block); -err_reg_pm_notifier: - free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery); -err_request_chrg_irq: - free_irq(gpio_to_irq(GPIO_LPC_INT), chip); -err_request_lpc_irq: - power_supply_unregister(&n516_battery); -err_bat_reg: - input_unregister_device(input); -err_input_register: - input_free_device(input); -err_input_alloc: - gpio_free(GPIO_CHARG_STAT_N); -err_gpio_req_chargstat: - gpio_free(GPIO_LPC_INT); -err_gpio_req_lpcint: - i2c_set_clientdata(client, NULL); - kfree(chip); - - return ret; -} - -static int __devexit n516_lpc_remove(struct i2c_client *client) -{ - struct n516_lpc_chip *chip = i2c_get_clientdata(client); - - unregister_pm_notifier(&n516_lpc_notif_block); - pm_power_off = NULL; - free_irq(gpio_to_irq(GPIO_CHARG_STAT_N), &n516_battery); - free_irq(gpio_to_irq(GPIO_LPC_INT), chip); - power_supply_unregister(&n516_battery); - input_unregister_device(chip->input); - gpio_free(GPIO_CHARG_STAT_N); - gpio_free(GPIO_LPC_INT); - i2c_set_clientdata(client, NULL); - kfree(chip); - - return 0; -} - -#if CONFIG_PM -static int n516_lpc_suspend(struct i2c_client *client, pm_message_t msg) -{ - if (!the_lpc->can_sleep) - return -EBUSY; - - if (device_may_wakeup(&client->dev)) - enable_irq_wake(gpio_to_irq(GPIO_LPC_INT)); - - return 0; -} - -static int n516_lpc_resume(struct i2c_client *client) -{ - if (device_may_wakeup(&client->dev)) - disable_irq_wake(gpio_to_irq(GPIO_LPC_INT)); - - return 0; -} -#else -#define n516_lpc_suspend NULL -#define n516_lpc_resume NULL -#endif - - -static struct i2c_driver n516_lpc_driver = { - .class = I2C_CLASS_HWMON, - .driver = { - .name = "n516-keys", - .owner = THIS_MODULE, - }, - .probe = n516_lpc_probe, - .remove = __devexit_p(n516_lpc_remove), - .detect = n516_lpc_detect, - .id_table = n516_lpc_i2c_ids, - .address_data = &addr_data, - .suspend = n516_lpc_suspend, - .resume = n516_lpc_resume, -}; - -static int __init n516_lpc_init(void) -{ - return i2c_add_driver(&n516_lpc_driver); -} - -static void __exit n516_lpc_exit(void) -{ - i2c_del_driver(&n516_lpc_driver); -} - - -module_init(n516_lpc_init); -module_exit(n516_lpc_exit); - -MODULE_AUTHOR("Yauhen Kharuzhy"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Keys and power controller driver for N516"); -MODULE_ALIAS("platform:n516-keys"); - diff --git a/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n526-lpc.c b/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n526-lpc.c deleted file mode 100644 index 4ac5c7992d..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/i2c/chips/n526-lpc.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/input.h> -#include <linux/irq.h> -#include <linux/interrupt.h> - -#include <linux/workqueue.h> - -#include <asm/mach-jz4740/irq.h> -#include <asm/mach-jz4740/gpio.h> - -struct n526_lpc { - struct i2c_client *client; - struct input_dev *input; - - struct work_struct work; -}; - -static const unsigned int n526_lpc_keymap[] = { - [0x01] = KEY_PAGEUP, - [0x02] = KEY_PAGEDOWN, - [0x03] = KEY_VOLUMEUP, - [0x04] = KEY_VOLUMEDOWN, - [0x06] = KEY_1, - [0x07] = KEY_Q, - [0x08] = KEY_A, - [0x09] = KEY_Z, - [0x0a] = KEY_LEFTSHIFT, - [0x0b] = KEY_2, - [0x0c] = KEY_W, - [0x0d] = KEY_S, - [0x0e] = KEY_X, - [0x0f] = KEY_REFRESH, - [0x10] = KEY_3, - [0x11] = KEY_E, - [0x12] = KEY_D, - [0x13] = KEY_C, - [0x14] = KEY_DOCUMENTS, - [0x15] = KEY_4, - [0x16] = KEY_R, - [0x17] = KEY_F, - [0x18] = KEY_V, - [0x19] = KEY_MUTE, - [0x1a] = KEY_5, - [0x1b] = KEY_T, - [0x1c] = KEY_G, - [0x1d] = KEY_B, - [0x1e] = KEY_DELETE, - [0x1f] = KEY_6, - [0x20] = KEY_Y, - [0x21] = KEY_H, - [0x22] = KEY_N, - [0x23] = KEY_SPACE, - [0x24] = KEY_7, - [0x25] = KEY_U, - [0x26] = KEY_J, - [0x27] = KEY_M, -/* [0x28] = KEY_SYM, */ - [0x29] = KEY_8, - [0x2a] = KEY_I, - [0x2b] = KEY_K, - [0x2c] = KEY_MENU, - [0x2d] = KEY_LEFT, - [0x2e] = KEY_9, - [0x2f] = KEY_O, - [0x30] = KEY_L, - [0x31] = KEY_UP, - [0x32] = KEY_DOWN, - [0x33] = KEY_0, - [0x34] = KEY_P, - [0x35] = KEY_BACKSPACE, - [0x36] = KEY_ENTER, - [0x37] = KEY_RIGHT, -}; - -static void n526_lpc_irq_work(struct work_struct *work) -{ - int ret; - struct n526_lpc *n526_lpc = container_of(work, struct n526_lpc, work); - struct i2c_client *client = n526_lpc->client; - unsigned char raw_msg; - struct i2c_msg msg = {client->addr, client->flags | I2C_M_RD, 1, &raw_msg}; - unsigned char keycode; - - - ret = i2c_transfer(client->adapter, &msg, 1); - - if (ret != 1) { - dev_err(&client->dev, "Failed to read lpc status\n"); - } - - keycode = raw_msg & 0x7f; - - if (keycode < ARRAY_SIZE(n526_lpc_keymap)) { - input_report_key(n526_lpc->input, n526_lpc_keymap[keycode], - !(raw_msg & 0x80)); - input_sync(n526_lpc->input); - } -} - -static irqreturn_t n526_lpc_irq(int irq, void *dev_id) -{ - struct n526_lpc *n526_lpc = dev_id; - - schedule_work(&n526_lpc->work); - return IRQ_HANDLED; -} - -static int __devinit n526_lpc_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret; - size_t i; - struct n526_lpc *n526_lpc; - struct input_dev *input; - - n526_lpc = kmalloc(sizeof(*n526_lpc), GFP_KERNEL); - - if (!n526_lpc) { - dev_err(&client->dev, "Failed to allocate device structure\n"); - return -ENOMEM; - } - - input = input_allocate_device(); - if (!input) { - dev_err(&client->dev, "Failed to allocate input device\n"); - ret = -ENOMEM; - goto err_free; - } - - input->name = "n526-keys"; - input->phys = "n526-keys/input0"; - input->dev.parent = &client->dev; - input->id.bustype = BUS_I2C; - input->id.vendor = 0x0001; - input->id.product = 0x0001; - input->id.version = 0x0001; - - __set_bit(EV_KEY, input->evbit); - - for (i = 0; i < ARRAY_SIZE(n526_lpc_keymap); ++i) { - if (n526_lpc_keymap[i] != 0) - __set_bit(n526_lpc_keymap[i], input->keybit); - } - - ret = input_register_device(input); - - if (ret) { - dev_err(&client->dev, "Failed to register input device: %d\n", ret); - goto err_free_input; - } - - n526_lpc->client = client; - n526_lpc->input = input; - INIT_WORK(&n526_lpc->work, n526_lpc_irq_work); - - ret = request_irq(client->irq, n526_lpc_irq, IRQF_TRIGGER_FALLING, - "n526-lpc", n526_lpc); - if (ret) { - dev_err(&client->dev, "Failed to request irq: %d\n", ret); - goto err_unregister_input; - } - - i2c_set_clientdata(client, n526_lpc); - - return 0; - -err_unregister_input: - input_unregister_device(input); -err_free_input: - input_free_device(input); -err_free: - kfree(n526_lpc); - - return ret; -} - -static int n526_lpc_remove(struct i2c_client *client) -{ - struct n526_lpc *n526_lpc = i2c_get_clientdata(client); - - free_irq(client->irq, n526_lpc); - - i2c_set_clientdata(client, NULL); - input_unregister_device(n526_lpc->input); - input_free_device(n526_lpc->input); - kfree(n526_lpc); - - return 0; -} - -static const struct i2c_device_id n526_lpc_id[] = { - { "n526-lpc", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, n526_lpc_id); - -static struct i2c_driver n526_lpc_driver = { - .driver = { - .name = "n526-lpc", - .owner = THIS_MODULE, - }, - .probe = n526_lpc_probe, - .remove = n526_lpc_remove, - .id_table = n526_lpc_id, -}; - -static int __init n526_lpc_init(void) -{ - return i2c_add_driver(&n526_lpc_driver); -} -module_init(n526_lpc_init); - -static void __exit n526_lpc_exit(void) -{ - i2c_del_driver(&n526_lpc_driver); -} -module_exit(n526_lpc_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Lars-Peter Clausen"); -MODULE_DESCRIPTION("n526 keypad driver"); -MODULE_ALIAS("i2c:n526-keys"); diff --git a/target/linux/xburst/files-2.6.32/drivers/misc/jz4740-adc.c b/target/linux/xburst/files-2.6.32/drivers/misc/jz4740-adc.c deleted file mode 100644 index c60f939a43..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/misc/jz4740-adc.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4720/JZ4740 SoC ADC driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * This driver is meant to synchronize access to the adc core for the battery - * and touchscreen driver. Thus these drivers should use the adc driver as a - * parent. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/jz4740-adc.h> - -#define JZ_REG_ADC_ENABLE 0x00 -#define JZ_REG_ADC_CFG 0x04 -#define JZ_REG_ADC_CTRL 0x08 -#define JZ_REG_ADC_STATUS 0x0C -#define JZ_REG_ADC_SAME 0x10 -#define JZ_REG_ADC_WAIT 0x14 -#define JZ_REG_ADC_TOUCH 0x18 -#define JZ_REG_ADC_BATTERY 0x1C -#define JZ_REG_ADC_ADCIN 0x20 - -#define JZ_ADC_ENABLE_TOUCH BIT(2) -#define JZ_ADC_ENABLE_BATTERY BIT(1) -#define JZ_ADC_ENABLE_ADCIN BIT(0) - -#define JZ_ADC_CFG_SPZZ BIT(31) -#define JZ_ADC_CFG_EX_IN BIT(30) -#define JZ_ADC_CFG_DNUM_MASK (0x7 << 16) -#define JZ_ADC_CFG_DMA_ENABLE BIT(15) -#define JZ_ADC_CFG_XYZ_MASK (0x2 << 13) -#define JZ_ADC_CFG_SAMPLE_NUM_MASK (0x7 << 10) -#define JZ_ADC_CFG_CLKDIV (0xf << 5) -#define JZ_ADC_CFG_BAT_MB BIT(4) - -#define JZ_ADC_CFG_DNUM_OFFSET 16 -#define JZ_ADC_CFG_XYZ_OFFSET 13 -#define JZ_ADC_CFG_SAMPLE_NUM_OFFSET 10 -#define JZ_ADC_CFG_CLKDIV_OFFSET 5 - -#define JZ_ADC_IRQ_PENDOWN BIT(4) -#define JZ_ADC_IRQ_PENUP BIT(3) -#define JZ_ADC_IRQ_TOUCH BIT(2) -#define JZ_ADC_IRQ_BATTERY BIT(1) -#define JZ_ADC_IRQ_ADCIN BIT(0) - -#define JZ_ADC_TOUCH_TYPE1 BIT(31) -#define JZ_ADC_TOUCH_DATA1_MASK 0xfff -#define JZ_ADC_TOUCH_TYPE0 BIT(15) -#define JZ_ADC_TOUCH_DATA0_MASK 0xfff - -#define JZ_ADC_BATTERY_MASK 0xfff - -#define JZ_ADC_ADCIN_MASK 0xfff - -struct jz4740_adc { - struct resource *mem; - void __iomem *base; - - int irq; - - struct clk *clk; - unsigned int clk_ref; - - struct completion bat_completion; - struct completion adc_completion; - - spinlock_t lock; -}; - -static irqreturn_t jz4740_adc_irq(int irq, void *data) -{ - struct jz4740_adc *adc = data; - uint8_t status; - - status = readb(adc->base + JZ_REG_ADC_STATUS); - - if (status & JZ_ADC_IRQ_BATTERY) - complete(&adc->bat_completion); - if (status & JZ_ADC_IRQ_ADCIN) - complete(&adc->adc_completion); - - writeb(0xff, adc->base + JZ_REG_ADC_STATUS); - - return IRQ_HANDLED; -} - -static void jz4740_adc_enable_irq(struct jz4740_adc *adc, int irq) -{ - unsigned long flags; - uint8_t val; - - spin_lock_irqsave(&adc->lock, flags); - - val = readb(adc->base + JZ_REG_ADC_CTRL); - val &= ~irq; - writeb(val, adc->base + JZ_REG_ADC_CTRL); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static void jz4740_adc_disable_irq(struct jz4740_adc *adc, int irq) -{ - unsigned long flags; - uint8_t val; - - spin_lock_irqsave(&adc->lock, flags); - - val = readb(adc->base + JZ_REG_ADC_CTRL); - val |= irq; - writeb(val, adc->base + JZ_REG_ADC_CTRL); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static void jz4740_adc_enable_adc(struct jz4740_adc *adc, int engine) -{ - unsigned long flags; - uint8_t val; - - spin_lock_irqsave(&adc->lock, flags); - - val = readb(adc->base + JZ_REG_ADC_ENABLE); - val |= engine; - writeb(val, adc->base + JZ_REG_ADC_ENABLE); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static void jz4740_adc_disable_adc(struct jz4740_adc *adc, int engine) -{ - unsigned long flags; - uint8_t val; - - spin_lock_irqsave(&adc->lock, flags); - - val = readb(adc->base + JZ_REG_ADC_ENABLE); - val &= ~engine; - writeb(val, adc->base + JZ_REG_ADC_ENABLE); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static inline void jz4740_adc_set_cfg(struct jz4740_adc *adc, uint32_t mask, -uint32_t val) -{ - unsigned long flags; - uint32_t cfg; - - spin_lock_irqsave(&adc->lock, flags); - - cfg = readl(adc->base + JZ_REG_ADC_CFG); - - cfg &= ~mask; - cfg |= val; - - writel(cfg, adc->base + JZ_REG_ADC_CFG); - - spin_unlock_irqrestore(&adc->lock, flags); -} - -static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc) -{ - unsigned long flags; - - spin_lock_irqsave(&adc->lock, flags); - if (adc->clk_ref++ == 0) - clk_enable(adc->clk); - spin_unlock_irqrestore(&adc->lock, flags); -} - -static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc) -{ - unsigned long flags; - - spin_lock_irqsave(&adc->lock, flags); - if (--adc->clk_ref == 0) - clk_disable(adc->clk); - spin_unlock_irqrestore(&adc->lock, flags); -} - -long jz4740_adc_read_battery_voltage(struct device *dev, - enum jz_adc_battery_scale scale) -{ - struct jz4740_adc *adc = dev_get_drvdata(dev); - unsigned long t; - long long voltage; - uint16_t val; - - if (!adc) - return -ENODEV; - - jz4740_adc_clk_enable(adc); - - if (scale == JZ_ADC_BATTERY_SCALE_2V5) - jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, JZ_ADC_CFG_BAT_MB); - else - jz4740_adc_set_cfg(adc, JZ_ADC_CFG_BAT_MB, 0); - - jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_BATTERY); - jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_BATTERY); - - t = wait_for_completion_interruptible_timeout(&adc->bat_completion, - HZ); - - jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_BATTERY); - - if (t <= 0) { - jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_BATTERY); - return t ? t : -ETIMEDOUT; - } - - val = readw(adc->base + JZ_REG_ADC_BATTERY); - - jz4740_adc_clk_disable(adc); - - if (scale == JZ_ADC_BATTERY_SCALE_2V5) - voltage = (((long long)val) * 2500000LL) >> 12LL; - else - voltage = ((((long long)val) * 7395000LL) >> 12LL) + 33000LL; - - return voltage; -} -EXPORT_SYMBOL_GPL(jz4740_adc_read_battery_voltage); - -static ssize_t jz4740_adc_read_adcin(struct device *dev, - struct device_attribute *dev_attr, - char *buf) -{ - struct jz4740_adc *adc = dev_get_drvdata(dev); - unsigned long t; - uint16_t val; - - jz4740_adc_clk_enable(adc); - - jz4740_adc_enable_irq(adc, JZ_ADC_IRQ_ADCIN); - jz4740_adc_enable_adc(adc, JZ_ADC_ENABLE_ADCIN); - - t = wait_for_completion_interruptible_timeout(&adc->adc_completion, - HZ); - - jz4740_adc_disable_irq(adc, JZ_ADC_IRQ_ADCIN); - - if (t <= 0) { - jz4740_adc_disable_adc(adc, JZ_ADC_ENABLE_ADCIN); - return t ? t : -ETIMEDOUT; - } - - val = readw(adc->base + JZ_REG_ADC_ADCIN); - jz4740_adc_clk_disable(adc); - - return sprintf(buf, "%d\n", val); -} - -static DEVICE_ATTR(adcin, S_IRUGO, jz4740_adc_read_adcin, NULL); - -static int __devinit jz4740_adc_probe(struct platform_device *pdev) -{ - int ret; - struct jz4740_adc *adc; - - adc = kmalloc(sizeof(*adc), GFP_KERNEL); - - adc->irq = platform_get_irq(pdev, 0); - - if (adc->irq < 0) { - ret = adc->irq; - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); - goto err_free; - } - - adc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!adc->mem) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get platform mmio resource\n"); - goto err_free; - } - - adc->mem = request_mem_region(adc->mem->start, resource_size(adc->mem), - pdev->name); - - if (!adc->mem) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - goto err_free; - } - - adc->base = ioremap_nocache(adc->mem->start, resource_size(adc->mem)); - - if (!adc->base) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - goto err_release_mem_region; - } - - adc->clk = clk_get(&pdev->dev, "adc"); - - if (IS_ERR(adc->clk)) { - ret = PTR_ERR(adc->clk); - dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); - goto err_iounmap; - } - - init_completion(&adc->bat_completion); - init_completion(&adc->adc_completion); - - spin_lock_init(&adc->lock); - - adc->clk_ref = 0; - - platform_set_drvdata(pdev, adc); - - ret = request_irq(adc->irq, jz4740_adc_irq, 0, pdev->name, adc); - - if (ret) { - dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); - goto err_clk_put; - } - - ret = device_create_file(&pdev->dev, &dev_attr_adcin); - if (ret) { - dev_err(&pdev->dev, "Failed to create sysfs file: %d\n", ret); - goto err_free_irq; - } - - writeb(0x00, adc->base + JZ_REG_ADC_ENABLE); - writeb(0xff, adc->base + JZ_REG_ADC_CTRL); - - return 0; - -err_free_irq: - free_irq(adc->irq, adc); -err_clk_put: - clk_put(adc->clk); -err_iounmap: - platform_set_drvdata(pdev, NULL); - iounmap(adc->base); -err_release_mem_region: - release_mem_region(adc->mem->start, resource_size(adc->mem)); -err_free: - kfree(adc); - - return ret; -} - -static int __devexit jz4740_adc_remove(struct platform_device *pdev) -{ - struct jz4740_adc *adc = platform_get_drvdata(pdev); - - device_remove_file(&pdev->dev, &dev_attr_adcin); - - free_irq(adc->irq, adc); - - iounmap(adc->base); - release_mem_region(adc->mem->start, resource_size(adc->mem)); - - clk_put(adc->clk); - - platform_set_drvdata(pdev, NULL); - - kfree(adc); - - return 0; -} - -struct platform_driver jz4740_adc_driver = { - .probe = jz4740_adc_probe, - .remove = jz4740_adc_remove, - .driver = { - .name = "jz4740-adc", - .owner = THIS_MODULE, - }, -}; - -static int __init jz4740_adc_init(void) -{ - return platform_driver_register(&jz4740_adc_driver); -} -module_init(jz4740_adc_init); - -static void __exit jz4740_adc_exit(void) -{ - platform_driver_unregister(&jz4740_adc_driver); -} -module_exit(jz4740_adc_exit); - -MODULE_DESCRIPTION("JZ4720/JZ4740 SoC ADC driver"); -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:jz4740-adc"); -MODULE_ALIAS("platform:jz4720-adc"); diff --git a/target/linux/xburst/files-2.6.32/drivers/mmc/host/jz_mmc.c b/target/linux/xburst/files-2.6.32/drivers/mmc/host/jz_mmc.c deleted file mode 100644 index 6c42a12b89..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/mmc/host/jz_mmc.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ7420/JZ4740 GPIO SD/MMC controller driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/mmc/host.h> -#include <linux/io.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/scatterlist.h> -#include <linux/clk.h> -#include <linux/mmc/jz4740_mmc.h> - -#include <linux/gpio.h> -#include <asm/mach-jz4740/gpio.h> -#include <asm/cacheflush.h> -#include <linux/dma-mapping.h> - -#define JZ_REG_MMC_STRPCL 0x00 -#define JZ_REG_MMC_STATUS 0x04 -#define JZ_REG_MMC_CLKRT 0x08 -#define JZ_REG_MMC_CMDAT 0x0C -#define JZ_REG_MMC_RESTO 0x10 -#define JZ_REG_MMC_RDTO 0x14 -#define JZ_REG_MMC_BLKLEN 0x18 -#define JZ_REG_MMC_NOB 0x1C -#define JZ_REG_MMC_SNOB 0x20 -#define JZ_REG_MMC_IMASK 0x24 -#define JZ_REG_MMC_IREG 0x28 -#define JZ_REG_MMC_CMD 0x2C -#define JZ_REG_MMC_ARG 0x30 -#define JZ_REG_MMC_RESP_FIFO 0x34 -#define JZ_REG_MMC_RXFIFO 0x38 -#define JZ_REG_MMC_TXFIFO 0x3C - -#define JZ_MMC_STRPCL_EXIT_MULTIPLE BIT(7) -#define JZ_MMC_STRPCL_EXIT_TRANSFER BIT(6) -#define JZ_MMC_STRPCL_START_READWAIT BIT(5) -#define JZ_MMC_STRPCL_STOP_READWAIT BIT(4) -#define JZ_MMC_STRPCL_RESET BIT(3) -#define JZ_MMC_STRPCL_START_OP BIT(2) -#define JZ_MMC_STRPCL_CLOCK_CONTROL BIT(1) | BIT(0) -#define JZ_MMC_STRPCL_CLOCK_STOP BIT(0) -#define JZ_MMC_STRPCL_CLOCK_START BIT(1) - - -#define JZ_MMC_STATUS_IS_RESETTING BIT(15) -#define JZ_MMC_STATUS_SDIO_INT_ACTIVE BIT(14) -#define JZ_MMC_STATUS_PRG_DONE BIT(13) -#define JZ_MMC_STATUS_DATA_TRAN_DONE BIT(12) -#define JZ_MMC_STATUS_END_CMD_RES BIT(11) -#define JZ_MMC_STATUS_DATA_FIFO_AFULL BIT(10) -#define JZ_MMC_STATUS_IS_READWAIT BIT(9) -#define JZ_MMC_STATUS_CLK_EN BIT(8) -#define JZ_MMC_STATUS_DATA_FIFO_FULL BIT(7) -#define JZ_MMC_STATUS_DATA_FIFO_EMPTY BIT(6) -#define JZ_MMC_STATUS_CRC_RES_ERR BIT(5) -#define JZ_MMC_STATUS_CRC_READ_ERROR BIT(4) -#define JZ_MMC_STATUS_TIMEOUT_WRITE BIT(3) -#define JZ_MMC_STATUS_CRC_WRITE_ERROR BIT(2) -#define JZ_MMC_STATUS_TIMEOUT_RES BIT(1) -#define JZ_MMC_STATUS_TIMEOUT_READ BIT(0) - -#define JZ_MMC_STATUS_READ_ERROR_MASK (BIT(4) | BIT(0)) -#define JZ_MMC_STATUS_WRITE_ERROR_MASK (BIT(3) | BIT(2)) - - -#define JZ_MMC_CMDAT_IO_ABORT BIT(11) -#define JZ_MMC_CMDAT_BUS_WIDTH_4BIT BIT(10) -#define JZ_MMC_CMDAT_DMA_EN BIT(8) -#define JZ_MMC_CMDAT_INIT BIT(7) -#define JZ_MMC_CMDAT_BUSY BIT(6) -#define JZ_MMC_CMDAT_STREAM BIT(5) -#define JZ_MMC_CMDAT_WRITE BIT(4) -#define JZ_MMC_CMDAT_DATA_EN BIT(3) -#define JZ_MMC_CMDAT_RESPONSE_FORMAT BIT(2) | BIT(1) | BIT(0) -#define JZ_MMC_CMDAT_RSP_R1 1 -#define JZ_MMC_CMDAT_RSP_R2 2 -#define JZ_MMC_CMDAT_RSP_R3 3 - -#define JZ_MMC_IRQ_SDIO BIT(7) -#define JZ_MMC_IRQ_TXFIFO_WR_REQ BIT(6) -#define JZ_MMC_IRQ_RXFIFO_RD_REQ BIT(5) -#define JZ_MMC_IRQ_END_CMD_RES BIT(2) -#define JZ_MMC_IRQ_PRG_DONE BIT(1) -#define JZ_MMC_IRQ_DATA_TRAN_DONE BIT(0) - - -#define JZ_MMC_CLK_RATE 24000000 - -#define JZ4740_MMC_MAX_TIMEOUT 10000000 - -struct jz4740_mmc_host { - struct mmc_host *mmc; - struct platform_device *pdev; - struct jz4740_mmc_platform_data *pdata; - struct clk *clk; - - int irq; - int card_detect_irq; - - struct resource *mem; - void __iomem *base; - struct mmc_request *req; - struct mmc_command *cmd; - - int max_clock; - uint32_t cmdat; - - uint16_t irq_mask; - - spinlock_t lock; - struct timer_list clock_timer; - struct timer_list timeout_timer; - unsigned waiting:1; -}; - -static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host); - -static void jz4740_mmc_enable_irq(struct jz4740_mmc_host *host, unsigned int irq) -{ - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); - - host->irq_mask &= ~irq; - writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); - - spin_unlock_irqrestore(&host->lock, flags); -} - -static void jz4740_mmc_disable_irq(struct jz4740_mmc_host *host, unsigned int irq) -{ - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); - - host->irq_mask |= irq; - writew(host->irq_mask, host->base + JZ_REG_MMC_IMASK); - - spin_unlock_irqrestore(&host->lock, flags); -} - -static void jz4740_mmc_clock_enable(struct jz4740_mmc_host *host, bool start_transfer) -{ - uint16_t val = JZ_MMC_STRPCL_CLOCK_START; - - if (start_transfer) - val |= JZ_MMC_STRPCL_START_OP; - - writew(val, host->base + JZ_REG_MMC_STRPCL); -} - -static void jz4740_mmc_clock_disable(struct jz4740_mmc_host *host) -{ - uint16_t status; - writew(JZ_MMC_STRPCL_CLOCK_STOP, host->base + JZ_REG_MMC_STRPCL); - do { - status = readl(host->base + JZ_REG_MMC_STATUS); - } while (status & JZ_MMC_STATUS_CLK_EN); - -} - -static void jz4740_mmc_reset(struct jz4740_mmc_host *host) -{ - writew(JZ_MMC_STRPCL_RESET, host->base + JZ_REG_MMC_STRPCL); - udelay(10); - while(readw(host->base + JZ_REG_MMC_STATUS) & JZ_MMC_STATUS_IS_RESETTING); -} - -static void jz4740_mmc_request_done(struct jz4740_mmc_host *host) -{ - struct mmc_request *req; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - req = host->req; - host->req = NULL; - host->waiting = 0; - spin_unlock_irqrestore(&host->lock, flags); - - if (!unlikely(req)) - return; - -/* if (req->cmd->error != 0) { - printk("error\n"); - jz4740_mmc_reset(host); - }*/ - - mmc_request_done(host->mmc, req); -} - -static void jz4740_mmc_write_data(struct jz4740_mmc_host *host, struct mmc_data *data) { - struct scatterlist *sg; - uint32_t *sg_pointer; - int status; - unsigned int timeout; - size_t i, j; - - for (sg = data->sg; sg; sg = sg_next(sg)) { - sg_pointer = sg_virt(sg); - i = sg->length / 4; - j = i >> 3; - i = i & 0x7; - while (j) { - timeout = JZ4740_MMC_MAX_TIMEOUT; - do { - status = readw(host->base + JZ_REG_MMC_IREG); - } while (!(status & JZ_MMC_IRQ_TXFIFO_WR_REQ) && --timeout); - if (unlikely(timeout == 0)) - goto err_timeout; - - writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG); - - writel(sg_pointer[0], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[1], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[2], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[3], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[4], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[5], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[6], host->base + JZ_REG_MMC_TXFIFO); - writel(sg_pointer[7], host->base + JZ_REG_MMC_TXFIFO); - sg_pointer += 8; - --j; - } - if (i) { - timeout = JZ4740_MMC_MAX_TIMEOUT; - do { - status = readw(host->base + JZ_REG_MMC_IREG); - } while (!(status & JZ_MMC_IRQ_TXFIFO_WR_REQ) && --timeout); - if (unlikely(timeout == 0)) - goto err_timeout; - - writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG); - - while (i) { - writel(*sg_pointer, host->base + JZ_REG_MMC_TXFIFO); - ++sg_pointer; - --i; - } - } - data->bytes_xfered += sg->length; - } - - status = readl(host->base + JZ_REG_MMC_STATUS); - if (status & JZ_MMC_STATUS_WRITE_ERROR_MASK) - goto err; - - writew(JZ_MMC_IRQ_TXFIFO_WR_REQ, host->base + JZ_REG_MMC_IREG); - timeout = JZ4740_MMC_MAX_TIMEOUT; - do { - status = readl(host->base + JZ_REG_MMC_STATUS); - } while ((status & JZ_MMC_STATUS_DATA_TRAN_DONE) == 0 && --timeout); - - if (unlikely(timeout == 0)) - goto err_timeout; - writew(JZ_MMC_IRQ_DATA_TRAN_DONE, host->base + JZ_REG_MMC_IREG); - - return; -err_timeout: - host->req->cmd->error = -ETIMEDOUT; - data->error = -ETIMEDOUT; - return; -err: - if(status & (JZ_MMC_STATUS_TIMEOUT_WRITE)) { - host->req->cmd->error = -ETIMEDOUT; - data->error = -ETIMEDOUT; - } else { - host->req->cmd->error = -EILSEQ; - data->error = -EILSEQ; - } -} - -static void jz4740_mmc_timeout(unsigned long data) -{ - struct jz4740_mmc_host *host = (struct jz4740_mmc_host*)data; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - if (!host->waiting) { - spin_unlock_irqrestore(&host->lock, flags); - return; - } - - host->waiting = 0; - - spin_unlock_irqrestore(&host->lock, flags); - - host->req->cmd->error = -ETIMEDOUT; - jz4740_mmc_request_done(host); -} - -static void jz4740_mmc_read_data(struct jz4740_mmc_host *host, struct mmc_data *data) { - struct scatterlist *sg; - uint32_t *sg_pointer; - uint32_t d; - uint16_t status = 0; - size_t i, j; - unsigned int timeout; - - for (sg = data->sg; sg; sg = sg_next(sg)) { - sg_pointer = sg_virt(sg); - i = sg->length; - j = i >> 5; - i = i & 0x1f; - while (j) { - timeout = JZ4740_MMC_MAX_TIMEOUT; - do { - status = readw(host->base + JZ_REG_MMC_IREG); - } while (!(status & JZ_MMC_IRQ_RXFIFO_RD_REQ) && --timeout); - - if (unlikely(timeout == 0)) - goto err_timeout; - - writew(JZ_MMC_IRQ_RXFIFO_RD_REQ, host->base + JZ_REG_MMC_IREG); - - sg_pointer[0] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[1] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[2] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[3] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[4] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[5] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[6] = readl(host->base + JZ_REG_MMC_RXFIFO); - sg_pointer[7] = readl(host->base + JZ_REG_MMC_RXFIFO); - - sg_pointer += 8; - --j; - } - - while (i >= 4) { - timeout = JZ4740_MMC_MAX_TIMEOUT; - do { - status = readl(host->base + JZ_REG_MMC_STATUS); - } while ((status & JZ_MMC_STATUS_DATA_FIFO_EMPTY) && --timeout); - - if (unlikely(timeout == 0)) - goto err_timeout; - - *sg_pointer = readl(host->base + JZ_REG_MMC_RXFIFO); - ++sg_pointer; - i -= 4; - } - if (i > 0) { - d = readl(host->base + JZ_REG_MMC_RXFIFO); - memcpy(sg_pointer, &d, i); - } - data->bytes_xfered += sg->length; - - flush_dcache_page(sg_page(sg)); - } - - status = readl(host->base + JZ_REG_MMC_STATUS); - if (status & JZ_MMC_STATUS_READ_ERROR_MASK) - goto err; - - /* For whatever reason there is sometime one word more in the fifo then - * requested */ - while ((status & JZ_MMC_STATUS_DATA_FIFO_EMPTY) == 0 && --timeout) { - d = readl(host->base + JZ_REG_MMC_RXFIFO); - status = readl(host->base + JZ_REG_MMC_STATUS); - } - return; -err_timeout: - host->req->cmd->error = -ETIMEDOUT; - data->error = -ETIMEDOUT; - return; -err: - if(status & JZ_MMC_STATUS_TIMEOUT_READ) { - host->req->cmd->error = -ETIMEDOUT; - data->error = -ETIMEDOUT; - } else { - host->req->cmd->error = -EILSEQ; - data->error = -EILSEQ; - } -} - -static irqreturn_t jz_mmc_irq_worker(int irq, void *devid) -{ - struct jz4740_mmc_host *host = (struct jz4740_mmc_host*)devid; - - if (host->cmd->error) - jz4740_mmc_request_done(host); - else - jz4740_mmc_cmd_done(host); - - return IRQ_HANDLED; -} - -static irqreturn_t jz_mmc_irq(int irq, void *devid) -{ - struct jz4740_mmc_host *host = devid; - uint16_t irq_reg, status, tmp; - unsigned long flags; - irqreturn_t ret = IRQ_HANDLED; - - irq_reg = readw(host->base + JZ_REG_MMC_IREG); - - tmp = irq_reg; - spin_lock_irqsave(&host->lock, flags); - irq_reg &= ~host->irq_mask; - spin_unlock_irqrestore(&host->lock, flags); - - tmp &= ~(JZ_MMC_IRQ_TXFIFO_WR_REQ | JZ_MMC_IRQ_RXFIFO_RD_REQ | - JZ_MMC_IRQ_PRG_DONE | JZ_MMC_IRQ_DATA_TRAN_DONE); - - if (tmp != irq_reg) { - dev_warn(&host->pdev->dev, "Sparse irq: %x\n", tmp & ~irq_reg); - writew(tmp & ~irq_reg, host->base + JZ_REG_MMC_IREG); - } - - - if (irq_reg & JZ_MMC_IRQ_SDIO) { - writew(JZ_MMC_IRQ_SDIO, host->base + JZ_REG_MMC_IREG); - mmc_signal_sdio_irq(host->mmc); - } - - if (!host->req || !host->cmd) { - goto handled; - } - - - spin_lock_irqsave(&host->lock, flags); - if (!host->waiting) { - spin_unlock_irqrestore(&host->lock, flags); - goto handled; - } - - host->waiting = 0; - spin_unlock_irqrestore(&host->lock, flags); - - del_timer(&host->timeout_timer); - - status = readl(host->base + JZ_REG_MMC_STATUS); - - if (status & JZ_MMC_STATUS_TIMEOUT_RES) { - host->cmd->error = -ETIMEDOUT; - } else if (status & JZ_MMC_STATUS_CRC_RES_ERR) { - host->cmd->error = -EIO; - } else if(status & (JZ_MMC_STATUS_CRC_READ_ERROR | - JZ_MMC_STATUS_CRC_WRITE_ERROR)) { - host->cmd->data->error = -EIO; - } else if(status & (JZ_MMC_STATUS_CRC_READ_ERROR | - JZ_MMC_STATUS_CRC_WRITE_ERROR)) { - host->cmd->data->error = -EIO; - } - - if (irq_reg & JZ_MMC_IRQ_END_CMD_RES) { - jz4740_mmc_disable_irq(host, JZ_MMC_IRQ_END_CMD_RES); - writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG); - ret = IRQ_WAKE_THREAD; - } - - return ret; -handled: - - writew(0xff, host->base + JZ_REG_MMC_IREG); - return IRQ_HANDLED; -} - -static int jz4740_mmc_set_clock_rate(struct jz4740_mmc_host *host, int rate) { - int div = 0; - int real_rate; - - jz4740_mmc_clock_disable(host); - clk_set_rate(host->clk, JZ_MMC_CLK_RATE); - - real_rate = clk_get_rate(host->clk); - - while (real_rate > rate && div < 7) { - ++div; - real_rate >>= 1; - } - - writew(div, host->base + JZ_REG_MMC_CLKRT); - return real_rate; -} - - -static void jz4740_mmc_read_response(struct jz4740_mmc_host *host, struct mmc_command *cmd) -{ - int i; - uint16_t tmp; - if (cmd->flags & MMC_RSP_136) { - tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO); - for (i = 0; i < 4; ++i) { - cmd->resp[i] = tmp << 24; - cmd->resp[i] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) << 8; - tmp = readw(host->base + JZ_REG_MMC_RESP_FIFO); - cmd->resp[i] |= tmp >> 8; - } - } else { - cmd->resp[0] = readw(host->base + JZ_REG_MMC_RESP_FIFO) << 24; - cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) << 8; - cmd->resp[0] |= readw(host->base + JZ_REG_MMC_RESP_FIFO) & 0xff; - } -} - -static void jz4740_mmc_send_command(struct jz4740_mmc_host *host, struct mmc_command *cmd) -{ - uint32_t cmdat = host->cmdat; - - host->cmdat &= ~JZ_MMC_CMDAT_INIT; - jz4740_mmc_clock_disable(host); - - host->cmd = cmd; - - if (cmd->flags & MMC_RSP_BUSY) - cmdat |= JZ_MMC_CMDAT_BUSY; - - switch (mmc_resp_type(cmd)) { - case MMC_RSP_R1B: - case MMC_RSP_R1: - cmdat |= JZ_MMC_CMDAT_RSP_R1; - break; - case MMC_RSP_R2: - cmdat |= JZ_MMC_CMDAT_RSP_R2; - break; - case MMC_RSP_R3: - cmdat |= JZ_MMC_CMDAT_RSP_R3; - break; - default: - break; - } - - if (cmd->data) { - cmdat |= JZ_MMC_CMDAT_DATA_EN; - if (cmd->data->flags & MMC_DATA_WRITE) - cmdat |= JZ_MMC_CMDAT_WRITE; - if (cmd->data->flags & MMC_DATA_STREAM) - cmdat |= JZ_MMC_CMDAT_STREAM; - - writew(cmd->data->blksz, host->base + JZ_REG_MMC_BLKLEN); - writew(cmd->data->blocks, host->base + JZ_REG_MMC_NOB); - } - - writeb(cmd->opcode, host->base + JZ_REG_MMC_CMD); - writel(cmd->arg, host->base + JZ_REG_MMC_ARG); - writel(cmdat, host->base + JZ_REG_MMC_CMDAT); - - host->waiting = 1; - jz4740_mmc_clock_enable(host, 1); - mod_timer(&host->timeout_timer, jiffies + 5*HZ); -} - -static void jz4740_mmc_cmd_done(struct jz4740_mmc_host *host) -{ - uint32_t status; - struct mmc_command *cmd = host->req->cmd; - struct mmc_request *req = host->req; - unsigned int timeout = JZ4740_MMC_MAX_TIMEOUT; - - if (cmd->flags & MMC_RSP_PRESENT) - jz4740_mmc_read_response(host, cmd); - - if (cmd->data) { - if (cmd->data->flags & MMC_DATA_READ) - jz4740_mmc_read_data(host, cmd->data); - else - jz4740_mmc_write_data(host, cmd->data); - } - - if (req->stop) { - jz4740_mmc_send_command(host, req->stop); - do { - status = readw(host->base + JZ_REG_MMC_IREG); - } while ((status & JZ_MMC_IRQ_PRG_DONE) == 0 && --timeout); - writew(JZ_MMC_IRQ_PRG_DONE, host->base + JZ_REG_MMC_IREG); - } - - if (unlikely(timeout == 0)) - req->stop->error = -ETIMEDOUT; - - jz4740_mmc_request_done(host); -} - -static void jz4740_mmc_request(struct mmc_host *mmc, struct mmc_request *req) -{ - struct jz4740_mmc_host *host = mmc_priv(mmc); - - host->req = req; - - writew(0xffff, host->base + JZ_REG_MMC_IREG); - - writew(JZ_MMC_IRQ_END_CMD_RES, host->base + JZ_REG_MMC_IREG); - jz4740_mmc_enable_irq(host, JZ_MMC_IRQ_END_CMD_RES); - jz4740_mmc_send_command(host, req->cmd); -} - - -static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct jz4740_mmc_host *host = mmc_priv(mmc); - if (ios->clock) - jz4740_mmc_set_clock_rate(host, ios->clock); - - switch(ios->power_mode) { - case MMC_POWER_UP: - jz4740_mmc_reset(host); - if (gpio_is_valid(host->pdata->gpio_power)) - gpio_set_value(host->pdata->gpio_power, - !host->pdata->power_active_low); - host->cmdat |= JZ_MMC_CMDAT_INIT; - clk_enable(host->clk); - break; - case MMC_POWER_ON: - break; - default: - if (gpio_is_valid(host->pdata->gpio_power)) - gpio_set_value(host->pdata->gpio_power, - host->pdata->power_active_low); - clk_disable(host->clk); - break; - } - - switch(ios->bus_width) { - case MMC_BUS_WIDTH_1: - host->cmdat &= ~JZ_MMC_CMDAT_BUS_WIDTH_4BIT; - break; - case MMC_BUS_WIDTH_4: - host->cmdat |= JZ_MMC_CMDAT_BUS_WIDTH_4BIT; - break; - default: - dev_err(&host->pdev->dev, "Invalid bus width: %d\n", ios->bus_width); - } -} - -static int jz4740_mmc_get_ro(struct mmc_host *mmc) -{ - struct jz4740_mmc_host *host = mmc_priv(mmc); - if (!gpio_is_valid(host->pdata->gpio_read_only)) - return -ENOSYS; - - return gpio_get_value(host->pdata->gpio_read_only) ^ - host->pdata->read_only_active_low; -} - -static int jz4740_mmc_get_cd(struct mmc_host *mmc) -{ - struct jz4740_mmc_host *host = mmc_priv(mmc); - if (!gpio_is_valid(host->pdata->gpio_card_detect)) - return -ENOSYS; - - return gpio_get_value(host->pdata->gpio_card_detect) ^ - host->pdata->card_detect_active_low; -} - -static irqreturn_t jz4740_mmc_card_detect_irq(int irq, void *devid) -{ - struct jz4740_mmc_host *host = devid; - - mmc_detect_change(host->mmc, HZ / 3); - - return IRQ_HANDLED; -} - -static void jz4740_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) -{ - struct jz4740_mmc_host *host = mmc_priv(mmc); - if (enable) - jz4740_mmc_enable_irq(host, JZ_MMC_IRQ_SDIO); - else - jz4740_mmc_disable_irq(host, JZ_MMC_IRQ_SDIO); -} - -static const struct mmc_host_ops jz4740_mmc_ops = { - .request = jz4740_mmc_request, - .set_ios = jz4740_mmc_set_ios, - .get_ro = jz4740_mmc_get_ro, - .get_cd = jz4740_mmc_get_cd, - .enable_sdio_irq = jz4740_mmc_enable_sdio_irq, -}; - -static const struct jz_gpio_bulk_request jz4740_mmc_pins[] = { - JZ_GPIO_BULK_PIN(MSC_CMD), - JZ_GPIO_BULK_PIN(MSC_CLK), - JZ_GPIO_BULK_PIN(MSC_DATA0), - JZ_GPIO_BULK_PIN(MSC_DATA1), - JZ_GPIO_BULK_PIN(MSC_DATA2), - JZ_GPIO_BULK_PIN(MSC_DATA3), -}; - -static int __devinit jz4740_mmc_request_gpios(struct platform_device *pdev) -{ - int ret; - struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) - return 0; - - if (gpio_is_valid(pdata->gpio_card_detect)) { - ret = gpio_request(pdata->gpio_card_detect, "MMC detect change"); - if (ret) { - dev_err(&pdev->dev, "Failed to request detect change gpio\n"); - goto err; - } - gpio_direction_input(pdata->gpio_card_detect); - } - - if (gpio_is_valid(pdata->gpio_read_only)) { - ret = gpio_request(pdata->gpio_read_only, "MMC read only"); - if (ret) { - dev_err(&pdev->dev, "Failed to request read only gpio: %d\n", ret); - goto err_free_gpio_card_detect; - } - gpio_direction_input(pdata->gpio_read_only); - } - - if (gpio_is_valid(pdata->gpio_power)) { - ret = gpio_request(pdata->gpio_power, "MMC power"); - if (ret) { - dev_err(&pdev->dev, "Failed to request power gpio: %d\n", ret); - goto err_free_gpio_read_only; - } - gpio_direction_output(pdata->gpio_power, pdata->power_active_low); - } - - return 0; - -err_free_gpio_read_only: - if (gpio_is_valid(pdata->gpio_read_only)) - gpio_free(pdata->gpio_read_only); -err_free_gpio_card_detect: - if (gpio_is_valid(pdata->gpio_card_detect)) - gpio_free(pdata->gpio_card_detect); -err: - return ret; -} - -static void jz4740_mmc_free_gpios(struct platform_device *pdev) -{ - struct jz4740_mmc_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) - return; - - if (gpio_is_valid(pdata->gpio_power)) - gpio_free(pdata->gpio_power); - if (gpio_is_valid(pdata->gpio_read_only)) - gpio_free(pdata->gpio_read_only); - if (gpio_is_valid(pdata->gpio_card_detect)) - gpio_free(pdata->gpio_card_detect); -} - -static int __devinit jz4740_mmc_probe(struct platform_device* pdev) -{ - int ret; - struct mmc_host *mmc; - struct jz4740_mmc_host *host; - struct jz4740_mmc_platform_data *pdata; - - pdata = pdev->dev.platform_data; - - mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev); - - if (!mmc) { - dev_err(&pdev->dev, "Failed to alloc mmc host structure\n"); - return -ENOMEM; - } - - host = mmc_priv(mmc); - - host->irq = platform_get_irq(pdev, 0); - - if (host->irq < 0) { - ret = host->irq; - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); - goto err_free_host; - } - - host->clk = clk_get(&pdev->dev, "mmc"); - if (!host->clk) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get mmc clock\n"); - goto err_free_host; - } - - host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!host->mem) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get base platform memory\n"); - goto err_clk_put; - } - - host->mem = request_mem_region(host->mem->start, resource_size(host->mem), - pdev->name); - - if (!host->mem) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to request base memory region\n"); - goto err_clk_put; - } - - host->base = ioremap_nocache(host->mem->start, resource_size(host->mem)); - - if (!host->base) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to ioremap base memory\n"); - goto err_release_mem_region; - } - - if (pdata && pdata->data_1bit) - ret = jz_gpio_bulk_request(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3); - else - ret = jz_gpio_bulk_request(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins)); - - if (ret) { - dev_err(&pdev->dev, "Failed to request function pins: %d\n", ret); - goto err_iounmap; - } - - ret = jz4740_mmc_request_gpios(pdev); - if (ret) - goto err_gpio_bulk_free; - - mmc->ops = &jz4740_mmc_ops; - mmc->f_min = JZ_MMC_CLK_RATE / 128; - mmc->f_max = JZ_MMC_CLK_RATE; - mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = (pdata && pdata->data_1bit) ? 0 : MMC_CAP_4_BIT_DATA; - mmc->caps |= MMC_CAP_SDIO_IRQ; - mmc->max_seg_size = 4096; - mmc->max_phys_segs = 128; - - mmc->max_blk_size = (1 << 10) - 1; - mmc->max_blk_count = (1 << 15) - 1; - mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; - - host->mmc = mmc; - host->pdev = pdev; - host->pdata = pdata; - host->max_clock = JZ_MMC_CLK_RATE; - spin_lock_init(&host->lock); - host->irq_mask = 0xffff; - - host->card_detect_irq = gpio_to_irq(pdata->gpio_card_detect); - - if (host->card_detect_irq < 0) { - dev_warn(&pdev->dev, "Failed to get irq for card detect gpio\n"); - } else { - ret = request_irq(host->card_detect_irq, - jz4740_mmc_card_detect_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MMC/SD detect changed", host); - - if (ret) { - dev_err(&pdev->dev, "Failed to request card detect irq"); - goto err_free_gpios; - } - } - - ret = request_threaded_irq(host->irq, jz_mmc_irq, jz_mmc_irq_worker, IRQF_DISABLED, "MMC/SD", host); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); - goto err_free_card_detect_irq; - } - - jz4740_mmc_reset(host); - jz4740_mmc_clock_disable(host); - setup_timer(&host->timeout_timer, jz4740_mmc_timeout, (unsigned long)host); - - platform_set_drvdata(pdev, host); - ret = mmc_add_host(mmc); - - if (ret) { - dev_err(&pdev->dev, "Failed to add mmc host: %d\n", ret); - goto err_free_irq; - } - printk("JZ SD/MMC card driver registered\n"); - - return 0; - -err_free_irq: - free_irq(host->irq, host); -err_free_card_detect_irq: - if (host->card_detect_irq >= 0) - free_irq(host->card_detect_irq, host); -err_free_gpios: - jz4740_mmc_free_gpios(pdev); -err_gpio_bulk_free: - if (pdata && pdata->data_1bit) - jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3); - else - jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins)); -err_iounmap: - iounmap(host->base); -err_release_mem_region: - release_mem_region(host->mem->start, resource_size(host->mem)); -err_clk_put: - clk_put(host->clk); -err_free_host: - platform_set_drvdata(pdev, NULL); - mmc_free_host(mmc); - - return ret; -} - -static int jz4740_mmc_remove(struct platform_device *pdev) -{ - struct jz4740_mmc_host *host = platform_get_drvdata(pdev); - struct jz4740_mmc_platform_data *pdata = host->pdata; - - del_timer_sync(&host->timeout_timer); - jz4740_mmc_disable_irq(host, 0xff); - jz4740_mmc_reset(host); - - mmc_remove_host(host->mmc); - - free_irq(host->irq, host); - if (host->card_detect_irq >= 0) - free_irq(host->card_detect_irq, host); - - jz4740_mmc_free_gpios(pdev); - if (pdata && pdata->data_1bit) - jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3); - else - jz_gpio_bulk_free(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins)); - - iounmap(host->base); - release_mem_region(host->mem->start, resource_size(host->mem)); - - clk_put(host->clk); - - platform_set_drvdata(pdev, NULL); - mmc_free_host(host->mmc); - - return 0; -} - -#ifdef CONFIG_PM -static int jz4740_mmc_suspend(struct device *dev) -{ - struct jz4740_mmc_host *host = dev_get_drvdata(dev); - struct jz4740_mmc_platform_data *pdata = host->pdata; - - mmc_suspend_host(host->mmc, PMSG_SUSPEND); - - if (pdata && pdata->data_1bit) - jz_gpio_bulk_suspend(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3); - else - jz_gpio_bulk_suspend(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins)); - - return 0; -} - -static int jz4740_mmc_resume(struct device *dev) -{ - struct jz4740_mmc_host *host = dev_get_drvdata(dev); - struct jz4740_mmc_platform_data *pdata = host->pdata; - - if (pdata && pdata->data_1bit) - jz_gpio_bulk_resume(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins) - 3); - else - jz_gpio_bulk_resume(jz4740_mmc_pins, ARRAY_SIZE(jz4740_mmc_pins)); - - mmc_resume_host(host->mmc); - - return 0; -} - -struct dev_pm_ops jz4740_mmc_pm_ops = { - .suspend = jz4740_mmc_suspend, - .resume = jz4740_mmc_resume, - .poweroff = jz4740_mmc_suspend, - .restore = jz4740_mmc_resume, -}; - -#define jz4740_mmc_PM_OPS (&jz4740_mmc_pm_ops) -#else -#define jz4740_mmc_PM_OPS NULL -#endif - -static struct platform_driver jz4740_mmc_driver = { - .probe = jz4740_mmc_probe, - .remove = jz4740_mmc_remove, - .driver = { - .name = "jz4740-mmc", - .owner = THIS_MODULE, - .pm = jz4740_mmc_PM_OPS, - }, -}; - -static int __init jz4740_mmc_init(void) { - return platform_driver_register(&jz4740_mmc_driver); -} -module_init(jz4740_mmc_init); - -static void __exit jz4740_mmc_exit(void) { - platform_driver_unregister(&jz4740_mmc_driver); -} -module_exit(jz4740_mmc_exit); - -MODULE_DESCRIPTION("JZ4720/JZ4740 SD/MMC controller driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); diff --git a/target/linux/xburst/files-2.6.32/drivers/mtd/nand/jz4740_nand.c b/target/linux/xburst/files-2.6.32/drivers/mtd/nand/jz4740_nand.c deleted file mode 100644 index abe0caa86f..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/mtd/nand/jz4740_nand.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4720/JZ4740 SoC NAND controller driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/ioport.h> -#include <linux/platform_device.h> - -#include <linux/mtd/mtd.h> -#include <linux/mtd/nand.h> -#include <linux/mtd/partitions.h> - -#include <linux/mtd/jz4740_nand.h> -#include <linux/gpio.h> - -#define JZ_REG_NAND_CTRL 0x50 -#define JZ_REG_NAND_ECC_CTRL 0x100 -#define JZ_REG_NAND_DATA 0x104 -#define JZ_REG_NAND_PAR0 0x108 -#define JZ_REG_NAND_PAR1 0x10C -#define JZ_REG_NAND_PAR2 0x110 -#define JZ_REG_NAND_IRQ_STAT 0x114 -#define JZ_REG_NAND_IRQ_CTRL 0x118 -#define JZ_REG_NAND_ERR(x) (0x11C + (x << 2)) - -#define JZ_NAND_ECC_CTRL_PAR_READY BIT(4) -#define JZ_NAND_ECC_CTRL_ENCODING BIT(3) -#define JZ_NAND_ECC_CTRL_RS BIT(2) -#define JZ_NAND_ECC_CTRL_RESET BIT(1) -#define JZ_NAND_ECC_CTRL_ENABLE BIT(0) - -#define JZ_NAND_STATUS_ERR_COUNT (BIT(31) | BIT(30) | BIT(29)) -#define JZ_NAND_STATUS_PAD_FINISH BIT(4) -#define JZ_NAND_STATUS_DEC_FINISH BIT(3) -#define JZ_NAND_STATUS_ENC_FINISH BIT(2) -#define JZ_NAND_STATUS_UNCOR_ERROR BIT(1) -#define JZ_NAND_STATUS_ERROR BIT(0) - -#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT(x << 1) -#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT((x << 1) + 1) - -#define JZ_NAND_DATA_ADDR ((void __iomem *)0xB8000000) -#define JZ_NAND_CMD_ADDR (JZ_NAND_DATA_ADDR + 0x8000) -#define JZ_NAND_ADDR_ADDR (JZ_NAND_DATA_ADDR + 0x10000) - -struct jz_nand { - struct mtd_info mtd; - struct nand_chip chip; - void __iomem *base; - struct resource *mem; - - struct jz_nand_platform_data *pdata; - bool is_reading; -}; - -static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) -{ - return container_of(mtd, struct jz_nand, mtd); -} - -static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) -{ - struct jz_nand *nand = mtd_to_jz_nand(mtd); - struct nand_chip *chip = mtd->priv; - uint32_t reg; - - if (ctrl & NAND_CTRL_CHANGE) { - BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE)); - if (ctrl & NAND_ALE) - chip->IO_ADDR_W = JZ_NAND_ADDR_ADDR; - else if (ctrl & NAND_CLE) - chip->IO_ADDR_W = JZ_NAND_CMD_ADDR; - else - chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; - - reg = readl(nand->base + JZ_REG_NAND_CTRL); - if ( ctrl & NAND_NCE ) - reg |= JZ_NAND_CTRL_ASSERT_CHIP(0); - else - reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(0); - writel(reg, nand->base + JZ_REG_NAND_CTRL); - } - if (dat != NAND_CMD_NONE) - writeb(dat, chip->IO_ADDR_W); -} - -static int jz_nand_dev_ready(struct mtd_info *mtd) -{ - struct jz_nand *nand = mtd_to_jz_nand(mtd); - return gpio_get_value_cansleep(nand->pdata->busy_gpio); -} - -static void jz_nand_hwctl(struct mtd_info *mtd, int mode) -{ - struct jz_nand *nand = mtd_to_jz_nand(mtd); - uint32_t reg; - - - writel(0, nand->base + JZ_REG_NAND_IRQ_STAT); - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); - - reg |= JZ_NAND_ECC_CTRL_RESET; - reg |= JZ_NAND_ECC_CTRL_ENABLE; - reg |= JZ_NAND_ECC_CTRL_RS; - - switch(mode) { - case NAND_ECC_READ: - reg &= ~JZ_NAND_ECC_CTRL_ENCODING; - nand->is_reading = true; - break; - case NAND_ECC_WRITE: - reg |= JZ_NAND_ECC_CTRL_ENCODING; - nand->is_reading = false; - break; - default: - break; - } - - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); -} - - -static int jz_nand_calculate_ecc_rs(struct mtd_info* mtd, const uint8_t* dat, - uint8_t *ecc_code) -{ - struct jz_nand *nand = mtd_to_jz_nand(mtd); - uint32_t reg, status; - int i; - static uint8_t all_ff_ecc[] = {0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f}; - - if (nand->is_reading) - return 0; - - do { - status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); - } while(!(status & JZ_NAND_STATUS_ENC_FINISH)); - - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); - reg &= ~JZ_NAND_ECC_CTRL_ENABLE; - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); - - for (i = 0; i < 9; ++i) { - ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i); - } - - /* If the written data is completly 0xff, we also want to write 0xff as - * ecc, otherwise we will get in trouble when doing subpage writes. */ - if (memcmp(ecc_code, all_ff_ecc, 9) == 0) { - memset(ecc_code, 0xff, 9); - } - - return 0; -} - -/*#define printkd printk*/ -#define printkd(...) - -static void correct_data(uint8_t *dat, int index, int mask) -{ - int offset = index & 0x7; - uint16_t data; - printkd("correct: "); - - index += (index >> 3); - - data = dat[index]; - data |= dat[index+1] << 8; - - printkd("0x%x -> ", data); - - mask ^= (data >> offset) & 0x1ff; - data &= ~(0x1ff << offset); - data |= (mask << offset); - - printkd("0x%x\n", data); - - dat[index] = data & 0xff; - dat[index+1] = (data >> 8) & 0xff; -} - -static int jz_nand_correct_ecc_rs(struct mtd_info* mtd, uint8_t *dat, - uint8_t *read_ecc, uint8_t *calc_ecc) -{ - struct jz_nand *nand = mtd_to_jz_nand(mtd); - int i, error_count, index; - uint32_t reg, status, error; - uint32_t t; - - t = read_ecc[0]; - - if (t == 0xff) { - for (i = 1; i < 9; ++i) - t &= read_ecc[i]; - - t &= dat[0]; - t &= dat[nand->chip.ecc.size / 2]; - t &= dat[nand->chip.ecc.size - 1]; - - if (t == 0xff) { - for (i = 1; i < nand->chip.ecc.size - 1; ++i) - t &= dat[i]; - if (t == 0xff) - return 0; - } - } - - for(i = 0; i < 9; ++i) - writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); - - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); - reg |= JZ_NAND_ECC_CTRL_PAR_READY; - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); - - do { - status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); - } while (!(status & JZ_NAND_STATUS_DEC_FINISH)); - - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); - reg &= ~JZ_NAND_ECC_CTRL_ENABLE; - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); - - if (status & JZ_NAND_STATUS_ERROR) { - if (status & JZ_NAND_STATUS_UNCOR_ERROR) { - printkd("uncorrectable ecc:"); - for(i = 0; i < 9; ++i) - printkd(" 0x%x", read_ecc[i]); - printkd("\n"); - printkd("uncorrectable data:"); - for(i = 0; i < 32; ++i) - printkd(" 0x%x", dat[i]); - printkd("\n"); - return -1; - } - - error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; - - printkd("error_count: %d %x\n", error_count, status); - - for(i = 0; i < error_count; ++i) { - error = readl(nand->base + JZ_REG_NAND_ERR(i)); - index = ((error >> 16) & 0x1ff) - 1; - if (index >= 0 && index < 512) { - correct_data(dat, index, error & 0x1ff); - } - } - - return error_count; - } - - return 0; -} - - - -#ifdef CONFIG_MTD_CMDLINE_PARTS -static const char *part_probes[] = {"cmdline", NULL}; -#endif - -static int __devinit jz_nand_probe(struct platform_device *pdev) -{ - int ret; - struct jz_nand *nand; - struct nand_chip *chip; - struct mtd_info *mtd; - struct jz_nand_platform_data *pdata = pdev->dev.platform_data; -#ifdef CONFIG_MTD_PARTITIONS - struct mtd_partition *partition_info; - int num_partitions = 0; -#endif - - nand = kzalloc(sizeof(*nand), GFP_KERNEL); - if (!nand) { - dev_err(&pdev->dev, "Failed to allocate device structure.\n"); - return -ENOMEM; - } - - nand->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!nand->mem) { - dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); - ret = -ENOENT; - goto err_free; - } - - nand->mem = request_mem_region(nand->mem->start, resource_size(nand->mem), - pdev->name); - - if (!nand->mem) { - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - ret = -EBUSY; - goto err_free; - } - - nand->base = ioremap(nand->mem->start, resource_size(nand->mem)); - - if (!nand->base) { - dev_err(&pdev->dev, "Faild to ioremap mmio memory region\n"); - ret = -EBUSY; - goto err_release_mem; - } - - if (pdata && gpio_is_valid(pdata->busy_gpio)) { - ret = gpio_request(pdata->busy_gpio, "jz nand busy line"); - if (ret) { - dev_err(&pdev->dev, "Failed to request busy gpio %d: %d\n", - pdata->busy_gpio, ret); - goto err_iounmap; - } - } - - mtd = &nand->mtd; - chip = &nand->chip; - mtd->priv = chip; - mtd->owner = THIS_MODULE; - mtd->name = "jz4740-nand"; - - chip->ecc.hwctl = jz_nand_hwctl; - - chip->ecc.calculate = jz_nand_calculate_ecc_rs; - chip->ecc.correct = jz_nand_correct_ecc_rs; - chip->ecc.mode = NAND_ECC_HW_OOB_FIRST; - chip->ecc.size = 512; - chip->ecc.bytes = 9; - if (pdata) - chip->ecc.layout = pdata->ecc_layout; - - chip->chip_delay = 50; - chip->cmd_ctrl = jz_nand_cmd_ctrl; - - if (pdata && gpio_is_valid(pdata->busy_gpio)) - chip->dev_ready = jz_nand_dev_ready; - - chip->IO_ADDR_R = JZ_NAND_DATA_ADDR; - chip->IO_ADDR_W = JZ_NAND_DATA_ADDR; - - nand->pdata = pdata; - platform_set_drvdata(pdev, nand); - - ret = nand_scan_ident(mtd, 1); - if (ret) { - dev_err(&pdev->dev, "Failed to scan nand\n"); - goto err_gpio_free; - } - - if (pdata && pdata->ident_callback) { - pdata->ident_callback(pdev, chip, &pdata->partitions, &pdata->num_partitions); - } - - ret = nand_scan_tail(mtd); - if (ret) { - dev_err(&pdev->dev, "Failed to scan nand\n"); - goto err_gpio_free; - } - -#ifdef CONFIG_MTD_PARTITIONS -#ifdef CONFIG_MTD_CMDLINE_PARTS - num_partitions = parse_mtd_partitions(mtd, part_probes, - &partition_info, 0); -#endif - if (num_partitions <= 0 && pdata) { - num_partitions = pdata->num_partitions; - partition_info = pdata->partitions; - } - - if (num_partitions > 0) - ret = add_mtd_partitions(mtd, partition_info, num_partitions); - else -#endif - ret = add_mtd_device(mtd); - - if (ret) { - dev_err(&pdev->dev, "Failed to add mtd device\n"); - goto err_nand_release; - } - - dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n"); - - return 0; -err_nand_release: - nand_release(&nand->mtd); -err_gpio_free: - platform_set_drvdata(pdev, NULL); - gpio_free(pdata->busy_gpio); -err_iounmap: - iounmap(nand->base); -err_release_mem: - release_mem_region(nand->mem->start, resource_size(nand->mem)); -err_free: - kfree(nand); - return ret; -} - -static void __devexit jz_nand_remove(struct platform_device *pdev) -{ - struct jz_nand *nand = platform_get_drvdata(pdev); - - nand_release(&nand->mtd); - - iounmap(nand->base); - - release_mem_region(nand->mem->start, resource_size(nand->mem)); - - platform_set_drvdata(pdev, NULL); - kfree(nand); -} - -struct platform_driver jz_nand_driver = { - .probe = jz_nand_probe, - .remove = __devexit_p(jz_nand_probe), - .driver = { - .name = "jz4740-nand", - .owner = THIS_MODULE, - }, -}; - -static int __init jz_nand_init(void) -{ - return platform_driver_register(&jz_nand_driver); -} -module_init(jz_nand_init); - -static void __exit jz_nand_exit(void) -{ - platform_driver_unregister(&jz_nand_driver); -} -module_exit(jz_nand_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_DESCRIPTION("NAND controller driver for JZ4720/JZ4740 SoC"); -MODULE_ALIAS("platform:jz4740-nand"); -MODULE_ALIAS("platform:jz4720-nand"); diff --git a/target/linux/xburst/files-2.6.32/drivers/power/gpio-charger.c b/target/linux/xburst/files-2.6.32/drivers/power/gpio-charger.c deleted file mode 100644 index 95c6ba71d4..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/power/gpio-charger.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> - * Driver for chargers indicating their status through a GPIO pin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/power_supply.h> -#include <linux/interrupt.h> -#include <linux/gpio.h> - -#include <linux/power/gpio-charger.h> - -struct gpio_charger { - const struct gpio_charger_platform_data *pdata; - - int irq; - - struct power_supply charger; -}; - -static irqreturn_t gpio_charger_irq(int irq, void *devid) -{ - struct power_supply *charger = devid; - power_supply_changed(charger); - - return IRQ_HANDLED; -} - -static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) -{ - return container_of(psy, struct gpio_charger, charger); -} - -static int gpio_charger_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy); - const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; - - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = gpio_get_value(pdata->gpio); - val->intval ^= pdata->gpio_active_low; - break; - default: - return -EINVAL; - } - - return 0; -} - -static enum power_supply_property gpio_charger_properties[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static int __devinit gpio_charger_probe(struct platform_device *pdev) -{ - const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; - struct gpio_charger *gpio_charger; - struct power_supply *charger; - int ret; - - if (!pdata) { - dev_err(&pdev->dev, "No platform data"); - return -EINVAL; - } - - gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); - - charger = &gpio_charger->charger; - - charger->name = pdata->name; - charger->type = pdata->type; - charger->properties = gpio_charger_properties; - charger->num_properties = ARRAY_SIZE(gpio_charger_properties); - charger->get_property = gpio_charger_get_property; - charger->supplied_to = pdata->batteries; - charger->num_supplicants = pdata->num_batteries; - - if (gpio_is_valid(pdata->gpio)) { - ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); - if (ret) { - dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret); - goto err; - } - ret = gpio_direction_input(pdata->gpio); - if (ret) { - dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret); - goto err_gpio_free; - } - - gpio_charger->irq = gpio_to_irq(pdata->gpio); - if (gpio_charger->irq >= 0) { - ret = request_irq(gpio_charger->irq, gpio_charger_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - dev_name(&pdev->dev), charger); - if (ret) { - dev_warn(&pdev->dev, "Failed to request online gpio irq: %d\n", ret); - gpio_charger->irq = -1; - } - } - } - - ret = power_supply_register(&pdev->dev, charger); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret); - goto err_gpio_free; - } - - gpio_charger->pdata = pdata; - platform_set_drvdata(pdev, gpio_charger); - - return 0; - -err_gpio_free: - if (gpio_is_valid(pdata->gpio)) { - if (gpio_charger->irq >= 0) - free_irq(gpio_charger->irq, charger); - gpio_free(pdata->gpio); - } -err: - return ret; -} - -static int __devexit gpio_charger_remove(struct platform_device *pdev) -{ - struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); - const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; - - power_supply_unregister(&gpio_charger->charger); - - if (gpio_is_valid(pdata->gpio)) { - if (gpio_charger->irq >= 0) - free_irq(gpio_charger->irq, &gpio_charger->charger); - gpio_free(pdata->gpio); - } - - platform_set_drvdata(pdev, NULL); - kfree(gpio_charger); - - return 0; -} - -static struct platform_driver gpio_charger_driver = { - .probe = gpio_charger_probe, - .remove = __devexit_p(gpio_charger_remove), - .driver = { - .name = "gpio-charger", - .owner = THIS_MODULE, - }, -}; - -static int __init gpio_charger_init(void) -{ - return platform_driver_register(&gpio_charger_driver); -} -module_init(gpio_charger_init); - -static void gpio_charger_exit(void) -{ - platform_driver_unregister(&gpio_charger_driver); -} -module_exit(gpio_charger_exit); - -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_DESCRIPTION("Driver for chargers indicating their status through a gpio"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:gpio-charger"); diff --git a/target/linux/xburst/files-2.6.32/drivers/power/jz4740-battery.c b/target/linux/xburst/files-2.6.32/drivers/power/jz4740-battery.c deleted file mode 100644 index 70c80ebd72..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/power/jz4740-battery.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Battery measurement code for Ingenic JZ SOC. - * - * Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com> - * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> - * - * based on tosa_battery.c - * - * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com> -* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/power_supply.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <linux/interrupt.h> - -#include <linux/power/jz4740-battery.h> -#include <linux/jz4740-adc.h> - -struct jz_battery { - struct jz_battery_platform_data *pdata; - - int charge_irq; - - int status; - long voltage; - - struct power_supply battery; - struct delayed_work work; -}; - -static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) -{ - return container_of(psy, struct jz_battery, battery); -} - -static long jz_battery_read_voltage(struct jz_battery *jz_battery) -{ - struct device *adc = jz_battery->battery.dev->parent->parent; - enum jz_adc_battery_scale scale; - - if (jz_battery->pdata->info.voltage_max_design > 2500000) - scale = JZ_ADC_BATTERY_SCALE_7V5; - else - scale = JZ_ADC_BATTERY_SCALE_2V5; - - return jz4740_adc_read_battery_voltage(adc, scale); -} - -static int jz_battery_get_capacity(struct power_supply *psy) -{ - struct jz_battery *jz_battery = psy_to_jz_battery(psy); - struct power_supply_info *info = &jz_battery->pdata->info; - long voltage; - int ret; - int voltage_span; - - voltage = jz_battery_read_voltage(jz_battery); - - if (voltage < 0) - return voltage; - - voltage_span = info->voltage_max_design - info->voltage_min_design; - ret = ((voltage - info->voltage_min_design) * 100) / voltage_span; - - if (ret > 100) - ret = 100; - else if (ret < 0) - ret = 0; - - return ret; -} - -static int jz_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct jz_battery *jz_battery = psy_to_jz_battery(psy); - struct power_supply_info *info = &jz_battery->pdata->info; - long voltage; - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = jz_battery->status; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = jz_battery->pdata->info.technology; - break; - case POWER_SUPPLY_PROP_HEALTH: - voltage = jz_battery_read_voltage(jz_battery); - if (voltage < info->voltage_min_design) - val->intval = POWER_SUPPLY_HEALTH_DEAD; - else - val->intval = POWER_SUPPLY_HEALTH_GOOD; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = jz_battery_get_capacity(psy); - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = jz_battery_read_voltage(jz_battery); - if (val->intval < 0) - return val->intval; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: - val->intval = info->voltage_max_design; - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - val->intval = info->voltage_min_design; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = 1; - break; - default: - return -EINVAL; - } - return 0; -} - -static void jz_battery_external_power_changed(struct power_supply *psy) -{ - struct jz_battery *jz_battery = psy_to_jz_battery(psy); - - cancel_delayed_work(&jz_battery->work); - schedule_delayed_work(&jz_battery->work, 0); -} - -static irqreturn_t jz_battery_charge_irq(int irq, void *data) -{ - struct jz_battery *jz_battery = data; - - cancel_delayed_work(&jz_battery->work); - schedule_delayed_work(&jz_battery->work, 0); - - return IRQ_HANDLED; -} - -static void jz_battery_update(struct jz_battery *jz_battery) -{ - int status; - long voltage; - long voltage_difference; - bool has_changed = 0; - - if (gpio_is_valid(jz_battery->pdata->gpio_charge)) { - int is_charging; - - is_charging = gpio_get_value(jz_battery->pdata->gpio_charge); - is_charging ^= jz_battery->pdata->gpio_charge_active_low; - if (is_charging) - status = POWER_SUPPLY_STATUS_CHARGING; - else - status = POWER_SUPPLY_STATUS_NOT_CHARGING; - - if (status != jz_battery->status) { - jz_battery->status = status; - has_changed = 1; - } - } - - voltage = jz_battery_read_voltage(jz_battery); - voltage_difference = voltage - jz_battery->voltage; - if (voltage_difference > 50000 || voltage_difference < 50000) { - jz_battery->voltage = voltage; - has_changed = 1; - } - if (has_changed) - power_supply_changed(&jz_battery->battery); -} - -static enum power_supply_property jz_battery_properties[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_PRESENT, -}; - -static void jz_battery_work(struct work_struct *work) -{ - /* Too small interval will increase system workload */ - const int interval = HZ * 30; - struct jz_battery *jz_battery = container_of(work, struct jz_battery, - work.work); - - jz_battery_update(jz_battery); - schedule_delayed_work(&jz_battery->work, interval); -} - -static int jz_battery_probe(struct platform_device *pdev) -{ - int ret = 0; - struct jz_battery_platform_data *pdata = pdev->dev.platform_data; - struct jz_battery *jz_battery; - struct power_supply *battery; - - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "No platform data\n"); - return -EINVAL; - } - - jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); - - if (!jz_battery) { - dev_err(&pdev->dev, "Failed to allocate driver structure\n"); - return -ENOMEM; - } - - battery = &jz_battery->battery; - battery->name = pdata->info.name; - battery->type = POWER_SUPPLY_TYPE_BATTERY; - battery->properties = jz_battery_properties; - battery->num_properties = ARRAY_SIZE(jz_battery_properties); - battery->get_property = jz_battery_get_property; - battery->external_power_changed = jz_battery_external_power_changed; - battery->use_for_apm = 1; - - jz_battery->pdata = pdata; - - INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); - - if (gpio_is_valid(pdata->gpio_charge)) { - ret = gpio_request(pdata->gpio_charge, dev_name(&pdev->dev)); - if (ret) { - dev_err(&pdev->dev, "charger state gpio request failed.\n"); - goto err_free; - } - ret = gpio_direction_input(pdata->gpio_charge); - if (ret) { - dev_err(&pdev->dev, "charger state gpio set direction failed.\n"); - goto err_free_gpio; - } - - jz_battery->charge_irq = gpio_to_irq(pdata->gpio_charge); - - if (jz_battery->charge_irq >= 0) { - ret = request_irq(jz_battery->charge_irq, - jz_battery_charge_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - dev_name(&pdev->dev), jz_battery); - if (ret) { - dev_err(&pdev->dev, "Failed to request charge irq: %d\n", ret); - goto err_free_gpio; - } - } - } else { - jz_battery->charge_irq = -1; - } - - - ret = power_supply_register(&pdev->dev, &jz_battery->battery); - if (ret) { - dev_err(&pdev->dev, "power supply battery register failed.\n"); - goto err_free_irq; - } - - platform_set_drvdata(pdev, jz_battery); - schedule_delayed_work(&jz_battery->work, 0); - - return 0; - -err_free_irq: - if (jz_battery->charge_irq >= 0) - free_irq(jz_battery->charge_irq, jz_battery); -err_free_gpio: - if (gpio_is_valid(pdata->gpio_charge)) - gpio_free(jz_battery->pdata->gpio_charge); -err_free: - kfree(jz_battery); - return ret; -} - -static int jz_battery_remove(struct platform_device *pdev) -{ - struct jz_battery *jz_battery = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&jz_battery->work); - - if (gpio_is_valid(jz_battery->pdata->gpio_charge)) { - if (jz_battery->charge_irq >= 0) - free_irq(jz_battery->charge_irq, jz_battery); - gpio_free(jz_battery->pdata->gpio_charge); - } - - power_supply_unregister(&jz_battery->battery); - - return 0; -} - -#ifdef CONFIG_PM -static int jz_battery_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct jz_battery *jz_battery = platform_get_drvdata(pdev); - - cancel_delayed_work_sync(&jz_battery->work); - jz_battery->status = POWER_SUPPLY_STATUS_UNKNOWN; - - return 0; -} - -static int jz_battery_resume(struct platform_device *pdev) -{ - struct jz_battery *jz_battery = platform_get_drvdata(pdev); - - schedule_delayed_work(&jz_battery->work, 0); - - return 0; -} -#else -#define jz_battery_suspend NULL -#define jz_battery_resume NULL -#endif - -static struct platform_driver jz_battery_driver = { - .probe = jz_battery_probe, - .remove = __devexit_p(jz_battery_remove), - .suspend = jz_battery_suspend, - .resume = jz_battery_resume, - .driver = { - .name = "jz4740-battery", - .owner = THIS_MODULE, - }, -}; - -static int __init jz_battery_init(void) -{ - return platform_driver_register(&jz_battery_driver); -} -module_init(jz_battery_init); - -static void __exit jz_battery_exit(void) -{ - platform_driver_unregister(&jz_battery_driver); -} -module_exit(jz_battery_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jiejing Zhang <kzjeef@gmail.com>"); -MODULE_DESCRIPTION("JZ4720/JZ4740 SoC battery driver"); diff --git a/target/linux/xburst/files-2.6.32/drivers/rtc/rtc-jz4740.c b/target/linux/xburst/files-2.6.32/drivers/rtc/rtc-jz4740.c deleted file mode 100644 index 03479a73f7..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/rtc/rtc-jz4740.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4720/JZ4740 SoC RTC driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/rtc.h> - -#define JZ_REG_RTC_CTRL 0x00 -#define JZ_REG_RTC_SEC 0x04 -#define JZ_REG_RTC_SEC_ALARM 0x08 -#define JZ_REG_RTC_REGULATOR 0x0C -#define JZ_REG_RTC_SCRATCHPAD 0x34 - -#define JZ_RTC_CTRL_WRDY BIT(7) -#define JZ_RTC_CTRL_1HZ BIT(6) -#define JZ_RTC_CTRL_1HZ_IRQ BIT(5) -#define JZ_RTC_CTRL_AF BIT(4) -#define JZ_RTC_CTRL_AF_IRQ BIT(3) -#define JZ_RTC_CTRL_AE BIT(2) -#define JZ_RTC_CTRL_ENABLE BIT(0) - -struct jz4740_rtc { - struct resource *mem; - void __iomem *base; - - struct rtc_device *rtc; - - unsigned int irq; - - spinlock_t lock; -}; - -static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) -{ - return readl(rtc->base + reg); -} - -static inline void jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) -{ - uint32_t ctrl; - do { - ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); - } while (!(ctrl & JZ_RTC_CTRL_WRDY)); -} - - -static inline void jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, - uint32_t val) -{ - jz4740_rtc_wait_write_ready(rtc); - writel(val, rtc->base + reg); -} - -static void jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask, - uint32_t val) -{ - unsigned long flags; - uint32_t ctrl; - - spin_lock_irqsave(&rtc->lock, flags); - - ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); - - /* Don't clear interrupt flags by accident */ - ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF; - - ctrl &= ~mask; - ctrl |= val; - - jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl); - - spin_unlock_irqrestore(&rtc->lock, flags); -} - -static inline struct jz4740_rtc *dev_to_rtc(struct device *dev) -{ - return dev_get_drvdata(dev); -} - -static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - uint32_t secs, secs2; - - secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); - secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); - - while (secs != secs2) { - secs = secs2; - secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); - } - - rtc_time_to_tm(secs, time); - - return rtc_valid_tm(time); -} - -static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - - if ((uint32_t)secs != secs) - return -EINVAL; - - jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs); - - return 0; -} - -static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - uint32_t secs, secs2; - uint32_t ctrl; - - secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); - secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); - - while (secs != secs2){ - secs = secs2; - secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); - } - - ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); - - alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE); - alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF); - - rtc_time_to_tm(secs, &alrm->time); - - return rtc_valid_tm(&alrm->time); -} - -static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - unsigned long secs; - - rtc_tm_to_time(&alrm->time, &secs); - - if ((uint32_t)secs != secs) - return -EINVAL; - - jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, (uint32_t)secs); - jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AE, - alrm->enabled ? JZ_RTC_CTRL_AE : 0); - - return 0; -} - -static int jz4740_rtc_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ_IRQ, - enabled ? JZ_RTC_CTRL_1HZ_IRQ : 0); - return 0; -} - - -static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct jz4740_rtc *rtc = dev_to_rtc(dev); - jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, - enabled ? JZ_RTC_CTRL_AF_IRQ : 0); - return 0; -} - -static struct rtc_class_ops jz4740_rtc_ops = { - .read_time = jz4740_rtc_read_time, - .set_mmss = jz4740_rtc_set_mmss, - .read_alarm = jz4740_rtc_read_alarm, - .set_alarm = jz4740_rtc_set_alarm, - .update_irq_enable = jz4740_rtc_update_irq_enable, - .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, -}; - -static irqreturn_t jz4740_rtc_irq(int irq, void *data) -{ - struct jz4740_rtc *rtc = data; - uint32_t ctrl; - unsigned long events = 0; - ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); - - if (ctrl & JZ_RTC_CTRL_1HZ) - events |= (RTC_UF | RTC_IRQF); - - if (ctrl & JZ_RTC_CTRL_AF) - events |= (RTC_AF | RTC_IRQF); - - rtc_update_irq(rtc->rtc, 1, events); - - jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, 0); - - return IRQ_HANDLED; -} - -static int __devinit jz4740_rtc_probe(struct platform_device *pdev) -{ - int ret; - struct jz4740_rtc *rtc; - uint32_t scratchpad; - - rtc = kmalloc(sizeof(*rtc), GFP_KERNEL); - - rtc->irq = platform_get_irq(pdev, 0); - - if (rtc->irq < 0) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get platform irq\n"); - goto err_free; - } - - rtc->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!rtc->mem) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get platform mmio memory\n"); - goto err_free; - } - - rtc->mem = request_mem_region(rtc->mem->start, resource_size(rtc->mem), - pdev->name); - - if (!rtc->mem) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - goto err_free; - } - - rtc->base = ioremap_nocache(rtc->mem->start, resource_size(rtc->mem)); - - if (!rtc->base) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - goto err_release_mem_region; - } - - platform_set_drvdata(pdev, rtc); - - rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &jz4740_rtc_ops, - THIS_MODULE); - - if (IS_ERR(rtc->rtc)) { - ret = PTR_ERR(rtc->rtc); - dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret); - goto err_iounmap; - } - - ret = request_irq(rtc->irq, jz4740_rtc_irq, 0, - pdev->name, rtc); - - if (ret) { - dev_err(&pdev->dev, "Failed to request rtc irq: %d\n", ret); - goto err_unregister_rtc; - } - - scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD); - if (scratchpad != 0x12345678) { - jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); - jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0); - } - - return 0; - -err_unregister_rtc: - rtc_device_unregister(rtc->rtc); -err_iounmap: - platform_set_drvdata(pdev, NULL); - iounmap(rtc->base); -err_release_mem_region: - release_mem_region(rtc->mem->start, resource_size(rtc->mem)); -err_free: - kfree(rtc); - - return ret; -} - -static int __devexit jz4740_rtc_remove(struct platform_device *pdev) -{ - struct jz4740_rtc *rtc = platform_get_drvdata(pdev); - - free_irq(rtc->irq, rtc); - - rtc_device_unregister(rtc->rtc); - - iounmap(rtc->base); - release_mem_region(rtc->mem->start, resource_size(rtc->mem)); - - kfree(rtc); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -struct platform_driver jz4740_rtc_driver = { - .probe = jz4740_rtc_probe, - .remove = __devexit_p(jz4740_rtc_remove), - .driver = { - .name = "jz4740-rtc", - .owner = THIS_MODULE, - }, -}; - -static int __init jz4740_rtc_init(void) -{ - return platform_driver_register(&jz4740_rtc_driver); -} -module_init(jz4740_rtc_init); - -static void __exit jz4740_rtc_exit(void) -{ - platform_driver_unregister(&jz4740_rtc_driver); -} -module_exit(jz4740_rtc_exit); - -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("RTC driver for the JZ4720/JZ4740 SoC\n"); -MODULE_ALIAS("platform:jz4740-rtc"); diff --git a/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.c b/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.c deleted file mode 100644 index 8c58494b91..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.c +++ /dev/null @@ -1,2440 +0,0 @@ -/* - * linux/drivers/usb/gadget/jz4740_udc.c - * - * Ingenic JZ4740 on-chip high speed USB device controller - * - * Copyright (C) 2006 - 2008 Ingenic Semiconductor Inc. - * Author: <jlwei@ingenic.cn> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -/* - * This device has ep0, two bulk-in/interrupt-in endpoints, and one bulk-out endpoint. - * - * - Endpoint numbering is fixed: ep0, ep1in-int, ep2in-bulk, ep1out-bulk. - * - DMA works with bulk-in (channel 1) and bulk-out (channel 2) endpoints. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/ioport.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> -#include <linux/usb.h> -#include <linux/usb/gadget.h> -#include <linux/clk.h> - -#include <asm/byteorder.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/mach-jz4740/jz4740.h> -#include <asm/mach-jz4740/clock.h> - -#include "jz4740_udc.h" - -#define JZ_REG_UDC_FADDR 0x00 /* Function Address 8-bit */ -#define JZ_REG_UDC_POWER 0x01 /* Power Managemetn 8-bit */ -#define JZ_REG_UDC_INTRIN 0x02 /* Interrupt IN 16-bit */ -#define JZ_REG_UDC_INTROUT 0x04 /* Interrupt OUT 16-bit */ -#define JZ_REG_UDC_INTRINE 0x06 /* Intr IN enable 16-bit */ -#define JZ_REG_UDC_INTROUTE 0x08 /* Intr OUT enable 16-bit */ -#define JZ_REG_UDC_INTRUSB 0x0a /* Interrupt USB 8-bit */ - #define JZ_REG_UDC_INTRUSBE 0x0b /* Interrupt USB Enable 8-bit */ -#define JZ_REG_UDC_FRAME 0x0c /* Frame number 16-bit */ -#define JZ_REG_UDC_INDEX 0x0e /* Index register 8-bit */ -#define JZ_REG_UDC_TESTMODE 0x0f /* USB test mode 8-bit */ - -#define JZ_REG_UDC_CSR0 0x12 /* EP0 CSR 8-bit */ -#define JZ_REG_UDC_INMAXP 0x10 /* EP1-2 IN Max Pkt Size 16-bit */ -#define JZ_REG_UDC_INCSR 0x12 /* EP1-2 IN CSR LSB 8/16bit */ -#define JZ_REG_UDC_INCSRH 0x13 /* EP1-2 IN CSR MSB 8-bit */ -#define JZ_REG_UDC_OUTMAXP 0x14 /* EP1 OUT Max Pkt Size 16-bit */ -#define JZ_REG_UDC_OUTCSR 0x16 /* EP1 OUT CSR LSB 8/16bit */ -#define JZ_REG_UDC_OUTCSRH 0x17 /* EP1 OUT CSR MSB 8-bit */ -#define JZ_REG_UDC_OUTCOUNT 0x18 /* bytes in EP0/1 OUT FIFO 16-bit */ - -#define JZ_REG_UDC_EP_FIFO(x) (4 * (x) + 0x20) - -#define JZ_REG_UDC_EPINFO 0x78 /* Endpoint information */ -#define JZ_REG_UDC_RAMINFO 0x79 /* RAM information */ - -#define JZ_REG_UDC_INTR 0x200 /* DMA pending interrupts */ -#define JZ_REG_UDC_CNTL1 0x204 /* DMA channel 1 control */ -#define JZ_REG_UDC_ADDR1 0x208 /* DMA channel 1 AHB memory addr */ -#define JZ_REG_UDC_COUNT1 0x20c /* DMA channel 1 byte count */ -#define JZ_REG_UDC_CNTL2 0x214 /* DMA channel 2 control */ -#define JZ_REG_UDC_ADDR2 0x218 /* DMA channel 2 AHB memory addr */ -#define JZ_REG_UDC_COUNT2 0x21c /* DMA channel 2 byte count */ - -/* Power register bit masks */ -#define USB_POWER_SUSPENDM 0x01 -#define USB_POWER_RESUME 0x04 -#define USB_POWER_HSMODE 0x10 -#define USB_POWER_HSENAB 0x20 -#define USB_POWER_SOFTCONN 0x40 - -/* Interrupt register bit masks */ -#define USB_INTR_SUSPEND 0x01 -#define USB_INTR_RESUME 0x02 -#define USB_INTR_RESET 0x04 - -#define USB_INTR_EP0 0x0001 -#define USB_INTR_INEP1 0x0002 -#define USB_INTR_INEP2 0x0004 -#define USB_INTR_OUTEP1 0x0002 - -/* CSR0 bit masks */ -#define USB_CSR0_OUTPKTRDY 0x01 -#define USB_CSR0_INPKTRDY 0x02 -#define USB_CSR0_SENTSTALL 0x04 -#define USB_CSR0_DATAEND 0x08 -#define USB_CSR0_SETUPEND 0x10 -#define USB_CSR0_SENDSTALL 0x20 -#define USB_CSR0_SVDOUTPKTRDY 0x40 -#define USB_CSR0_SVDSETUPEND 0x80 - -/* Endpoint CSR register bits */ -#define USB_INCSRH_AUTOSET 0x80 -#define USB_INCSRH_ISO 0x40 -#define USB_INCSRH_MODE 0x20 -#define USB_INCSRH_DMAREQENAB 0x10 -#define USB_INCSRH_DMAREQMODE 0x04 -#define USB_INCSR_CDT 0x40 -#define USB_INCSR_SENTSTALL 0x20 -#define USB_INCSR_SENDSTALL 0x10 -#define USB_INCSR_FF 0x08 -#define USB_INCSR_UNDERRUN 0x04 -#define USB_INCSR_FFNOTEMPT 0x02 -#define USB_INCSR_INPKTRDY 0x01 -#define USB_OUTCSRH_AUTOCLR 0x80 -#define USB_OUTCSRH_ISO 0x40 -#define USB_OUTCSRH_DMAREQENAB 0x20 -#define USB_OUTCSRH_DNYT 0x10 -#define USB_OUTCSRH_DMAREQMODE 0x08 -#define USB_OUTCSR_CDT 0x80 -#define USB_OUTCSR_SENTSTALL 0x40 -#define USB_OUTCSR_SENDSTALL 0x20 -#define USB_OUTCSR_FF 0x10 -#define USB_OUTCSR_DATAERR 0x08 -#define USB_OUTCSR_OVERRUN 0x04 -#define USB_OUTCSR_FFFULL 0x02 -#define USB_OUTCSR_OUTPKTRDY 0x01 - -/* Testmode register bits */ -#define USB_TEST_SE0NAK 0x01 -#define USB_TEST_J 0x02 -#define USB_TEST_K 0x04 -#define USB_TEST_PACKET 0x08 - -/* DMA control bits */ -#define USB_CNTL_ENA 0x01 -#define USB_CNTL_DIR_IN 0x02 -#define USB_CNTL_MODE_1 0x04 -#define USB_CNTL_INTR_EN 0x08 -#define USB_CNTL_EP(n) ((n) << 4) -#define USB_CNTL_BURST_0 (0 << 9) -#define USB_CNTL_BURST_4 (1 << 9) -#define USB_CNTL_BURST_8 (2 << 9) -#define USB_CNTL_BURST_16 (3 << 9) - - -#ifndef DEBUG -# define DEBUG(fmt,args...) do {} while(0) -#endif -#ifndef DEBUG_EP0 -# define NO_STATES -# define DEBUG_EP0(fmt,args...) do {} while(0) -#endif -#ifndef DEBUG_SETUP -# define DEBUG_SETUP(fmt,args...) do {} while(0) -#endif - -static unsigned int use_dma = 0; /* 1: use DMA, 0: use PIO */ - -module_param(use_dma, int, 0); -MODULE_PARM_DESC(use_dma, "DMA mode enable flag"); - -struct jz4740_udc *the_controller; - -/* - * Local declarations. - */ -static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep); -static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr); - -static void done(struct jz4740_ep *ep, struct jz4740_request *req, - int status); -static void pio_irq_enable(struct jz4740_ep *ep); -static void pio_irq_disable(struct jz4740_ep *ep); -static void stop_activity(struct jz4740_udc *dev, - struct usb_gadget_driver *driver); -static void nuke(struct jz4740_ep *ep, int status); -static void flush(struct jz4740_ep *ep); -static void udc_set_address(struct jz4740_udc *dev, unsigned char address); - -/*-------------------------------------------------------------------------*/ - -/* inline functions of register read/write/set/clear */ - -static inline uint8_t usb_readb(struct jz4740_udc *udc, size_t reg) -{ - return readb(udc->base + reg); -} - -static inline uint16_t usb_readw(struct jz4740_udc *udc, size_t reg) -{ - return readw(udc->base + reg); -} - -static inline uint32_t usb_readl(struct jz4740_udc *udc, size_t reg) -{ - return readl(udc->base + reg); -} - -static inline void usb_writeb(struct jz4740_udc *udc, size_t reg, uint8_t val) -{ - writeb(val, udc->base + reg); -} - -static inline void usb_writew(struct jz4740_udc *udc, size_t reg, uint16_t val) -{ - writew(val, udc->base + reg); -} - -static inline void usb_writel(struct jz4740_udc *udc, size_t reg, uint32_t val) -{ - writel(val, udc->base + reg); -} - -static inline void usb_setb(struct jz4740_udc *udc, size_t reg, uint8_t mask) -{ - usb_writeb(udc, reg, usb_readb(udc, reg) | mask); -} - -static inline void usb_setw(struct jz4740_udc *udc, size_t reg, uint8_t mask) -{ - usb_writew(udc, reg, usb_readw(udc, reg) | mask); -} - -static inline void usb_setl(struct jz4740_udc *udc, size_t reg, uint32_t mask) -{ - usb_writel(udc, reg, usb_readl(udc, reg) | mask); -} - -static inline void usb_clearb(struct jz4740_udc *udc, size_t reg, uint8_t mask) -{ - usb_writeb(udc, reg, usb_readb(udc, reg) & ~mask); -} - -static inline void usb_clearw(struct jz4740_udc *udc, size_t reg, uint16_t mask) -{ - usb_writew(udc, reg, usb_readw(udc, reg) & ~mask); -} - -static inline void usb_clearl(struct jz4740_udc *udc, size_t reg, uint32_t mask) -{ - usb_writel(udc, reg, usb_readl(udc, reg) & ~mask); -} - -/*-------------------------------------------------------------------------*/ - -static inline void jz_udc_set_index(struct jz4740_udc *udc, uint8_t index) -{ - usb_writeb(udc, JZ_REG_UDC_INDEX, index); -} - -static inline void jz_udc_select_ep(struct jz4740_ep *ep) -{ - jz_udc_set_index(ep->dev, ep_index(ep)); -} - -static inline int write_packet(struct jz4740_ep *ep, - struct jz4740_request *req, int max) -{ - uint8_t *buf; - int length, nlong, nbyte; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - buf = req->req.buf + req->req.actual; - prefetch(buf); - - length = req->req.length - req->req.actual; - length = min(length, max); - req->req.actual += length; - - DEBUG("Write %d (max %d), fifo %x\n", length, max, ep->fifo); - - nlong = length >> 2; - nbyte = length & 0x3; - while (nlong--) { - usb_writel(ep->dev, ep->fifo, *((uint32_t *)buf)); - buf += 4; - } - while (nbyte--) { - usb_writeb(ep->dev, ep->fifo, *buf++); - } - - return length; -} - -static inline int read_packet(struct jz4740_ep *ep, - struct jz4740_request *req, int count) -{ - uint8_t *buf; - int length, nlong, nbyte; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - buf = req->req.buf + req->req.actual; - prefetchw(buf); - - length = req->req.length - req->req.actual; - length = min(length, count); - req->req.actual += length; - - DEBUG("Read %d, fifo %x\n", length, ep->fifo); - - nlong = length >> 2; - nbyte = length & 0x3; - while (nlong--) { - *((uint32_t *)buf) = usb_readl(ep->dev, ep->fifo); - buf += 4; - } - while (nbyte--) { - *buf++ = usb_readb(ep->dev, ep->fifo); - } - - return length; -} - -/*-------------------------------------------------------------------------*/ - -/* - * udc_disable - disable USB device controller - */ -static void udc_disable(struct jz4740_udc *dev) -{ - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - udc_set_address(dev, 0); - - /* Disable interrupts */ - usb_writew(dev, JZ_REG_UDC_INTRINE, 0); - usb_writew(dev, JZ_REG_UDC_INTROUTE, 0); - usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0); - - /* Disable DMA */ - usb_writel(dev, JZ_REG_UDC_CNTL1, 0); - usb_writel(dev, JZ_REG_UDC_CNTL2, 0); - - /* Disconnect from usb */ - usb_clearb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN); - - /* Disable the USB PHY */ - clk_disable(dev->clk); - - dev->ep0state = WAIT_FOR_SETUP; - dev->gadget.speed = USB_SPEED_UNKNOWN; - - return; -} - -/* - * udc_reinit - initialize software state - */ -static void udc_reinit(struct jz4740_udc *dev) -{ - int i; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - /* device/ep0 records init */ - INIT_LIST_HEAD(&dev->gadget.ep_list); - INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); - dev->ep0state = WAIT_FOR_SETUP; - - for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { - struct jz4740_ep *ep = &dev->ep[i]; - - if (i != 0) - list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); - - INIT_LIST_HEAD(&ep->queue); - ep->desc = 0; - ep->stopped = 0; - ep->pio_irqs = 0; - } -} - -/* until it's enabled, this UDC should be completely invisible - * to any USB host. - */ -static void udc_enable(struct jz4740_udc *dev) -{ - int i; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - /* UDC state is incorrect - Added by River */ - if (dev->state != UDC_STATE_ENABLE) { - return; - } - - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* Flush FIFO for each */ - for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { - struct jz4740_ep *ep = &dev->ep[i]; - - jz_udc_set_index(dev, ep_index(ep)); - flush(ep); - } - - /* Set this bit to allow the UDC entering low-power mode when - * there are no actions on the USB bus. - * UDC still works during this bit was set. - */ - jz4740_clock_udc_enable_auto_suspend(); - - /* Enable the USB PHY */ - clk_enable(dev->clk); - - /* Disable interrupts */ -/* usb_writew(dev, JZ_REG_UDC_INTRINE, 0); - usb_writew(dev, JZ_REG_UDC_INTROUTE, 0); - usb_writeb(dev, JZ_REG_UDC_INTRUSBE, 0);*/ - - /* Enable interrupts */ - usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_EP0); - usb_setb(dev, JZ_REG_UDC_INTRUSBE, USB_INTR_RESET); - /* Don't enable rest of the interrupts */ - /* usb_setw(dev, JZ_REG_UDC_INTRINE, USB_INTR_INEP1 | USB_INTR_INEP2); - usb_setw(dev, JZ_REG_UDC_INTROUTE, USB_INTR_OUTEP1); */ - - /* Enable SUSPEND */ - /* usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SUSPENDM); */ - - /* Enable HS Mode */ - usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_HSENAB); - - /* Let host detect UDC: - * Software must write a 1 to the PMR:USB_POWER_SOFTCONN bit to turn this - * transistor on and pull the USBDP pin HIGH. - */ - usb_setb(dev, JZ_REG_UDC_POWER, USB_POWER_SOFTCONN); - - return; -} - -/*-------------------------------------------------------------------------*/ - -/* keeping it simple: - * - one bus driver, initted first; - * - one function driver, initted second - */ - -/* - * Register entry point for the peripheral controller driver. - */ - -int usb_gadget_register_driver(struct usb_gadget_driver *driver) -{ - struct jz4740_udc *dev = the_controller; - int retval; - - if (!driver || !driver->bind) { - return -EINVAL; - } - - if (!dev) { - return -ENODEV; - } - - if (dev->driver) { - return -EBUSY; - } - - /* hook up the driver */ - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - - retval = driver->bind(&dev->gadget); - if (retval) { - DEBUG("%s: bind to driver %s --> error %d\n", dev->gadget.name, - driver->driver.name, retval); - dev->driver = 0; - return retval; - } - - /* then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. - */ - udc_enable(dev); - - DEBUG("%s: registered gadget driver '%s'\n", dev->gadget.name, - driver->driver.name); - - return 0; -} - -EXPORT_SYMBOL(usb_gadget_register_driver); - -static void stop_activity(struct jz4740_udc *dev, - struct usb_gadget_driver *driver) -{ - int i; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - /* don't disconnect drivers more than once */ - if (dev->gadget.speed == USB_SPEED_UNKNOWN) - driver = 0; - dev->gadget.speed = USB_SPEED_UNKNOWN; - - /* prevent new request submissions, kill any outstanding requests */ - for (i = 0; i < UDC_MAX_ENDPOINTS; i++) { - struct jz4740_ep *ep = &dev->ep[i]; - - ep->stopped = 1; - - jz_udc_set_index(dev, ep_index(ep)); - nuke(ep, -ESHUTDOWN); - } - - /* report disconnect; the driver is already quiesced */ - if (driver) { - spin_unlock(&dev->lock); - driver->disconnect(&dev->gadget); - spin_lock(&dev->lock); - } - - /* re-init driver-visible data structures */ - udc_reinit(dev); -} - - -/* - * Unregister entry point for the peripheral controller driver. - */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -{ - struct jz4740_udc *dev = the_controller; - unsigned long flags; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - if (!dev) - return -ENODEV; - if (!driver || driver != dev->driver) - return -EINVAL; - if (!driver->unbind) - return -EBUSY; - - spin_lock_irqsave(&dev->lock, flags); - dev->driver = 0; - stop_activity(dev, driver); - spin_unlock_irqrestore(&dev->lock, flags); - - driver->unbind(&dev->gadget); - - udc_disable(dev); - - DEBUG("unregistered driver '%s'\n", driver->driver.name); - - return 0; -} - -EXPORT_SYMBOL(usb_gadget_unregister_driver); - -/*-------------------------------------------------------------------------*/ - -/* - * Starting DMA using mode 1 - */ -static void kick_dma(struct jz4740_ep *ep, struct jz4740_request *req) -{ - struct jz4740_udc *dev = ep->dev; - uint32_t count = req->req.length; - uint32_t physaddr = virt_to_phys((void *)req->req.buf); - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - jz_udc_select_ep(ep); - - if (ep_is_in(ep)) { /* Bulk-IN transfer using DMA channel 1 */ - ep->reg_addr = JZ_REG_UDC_ADDR1; - - dma_cache_wback_inv((unsigned long)req->req.buf, count); - - pio_irq_enable(ep); - - usb_writeb(dev, JZ_REG_UDC_INCSRH, - USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE); - - usb_writel(dev, JZ_REG_UDC_ADDR1, physaddr); - usb_writel(dev, JZ_REG_UDC_COUNT1, count); - usb_writel(dev, JZ_REG_UDC_CNTL1, USB_CNTL_ENA | USB_CNTL_DIR_IN | USB_CNTL_MODE_1 | - USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep))); - } - else { /* Bulk-OUT transfer using DMA channel 2 */ - ep->reg_addr = JZ_REG_UDC_ADDR2; - - dma_cache_wback_inv((unsigned long)req->req.buf, count); - - pio_irq_enable(ep); - - usb_setb(dev, JZ_REG_UDC_OUTCSRH, - USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); - - usb_writel(dev, JZ_REG_UDC_ADDR2, physaddr); - usb_writel(dev, JZ_REG_UDC_COUNT2, count); - usb_writel(dev, JZ_REG_UDC_CNTL2, USB_CNTL_ENA | USB_CNTL_MODE_1 | - USB_CNTL_INTR_EN | USB_CNTL_BURST_16 | USB_CNTL_EP(ep_index(ep))); - } -} - -/*-------------------------------------------------------------------------*/ - -/** Write request to FIFO (max write == maxp size) - * Return: 0 = still running, 1 = completed, negative = errno - * NOTE: INDEX register must be set for EP - */ -static int write_fifo(struct jz4740_ep *ep, struct jz4740_request *req) -{ - struct jz4740_udc *dev = ep->dev; - uint32_t max, csr; - uint32_t physaddr = virt_to_phys((void *)req->req.buf); - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - max = le16_to_cpu(ep->desc->wMaxPacketSize); - - if (use_dma) { - uint32_t dma_count; - - /* DMA interrupt generated due to the last packet loaded into the FIFO */ - - dma_count = usb_readl(dev, ep->reg_addr) - physaddr; - req->req.actual += dma_count; - - if (dma_count % max) { - /* If the last packet is less than MAXP, set INPKTRDY manually */ - usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); - } - - done(ep, req, 0); - if (list_empty(&ep->queue)) { - pio_irq_disable(ep); - return 1; - } - else { - /* advance the request queue */ - req = list_entry(ep->queue.next, struct jz4740_request, queue); - kick_dma(ep, req); - return 0; - } - } - - /* - * PIO mode handling starts here ... - */ - - csr = usb_readb(dev, ep->csr); - - if (!(csr & USB_INCSR_FFNOTEMPT)) { - unsigned count; - int is_last, is_short; - - count = write_packet(ep, req, max); - usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); - - /* last packet is usually short (or a zlp) */ - if (unlikely(count != max)) - is_last = is_short = 1; - else { - if (likely(req->req.length != req->req.actual) - || req->req.zero) - is_last = 0; - else - is_last = 1; - /* interrupt/iso maxpacket may not fill the fifo */ - is_short = unlikely(max < ep_maxpacket(ep)); - } - - DEBUG("%s: wrote %s %d bytes%s%s %d left %p\n", __FUNCTION__, - ep->ep.name, count, - is_last ? "/L" : "", is_short ? "/S" : "", - req->req.length - req->req.actual, req); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - done(ep, req, 0); - if (list_empty(&ep->queue)) { - pio_irq_disable(ep); - } - return 1; - } - } else { - DEBUG("Hmm.. %d ep FIFO is not empty!\n", ep_index(ep)); - } - - return 0; -} - -/** Read to request from FIFO (max read == bytes in fifo) - * Return: 0 = still running, 1 = completed, negative = errno - * NOTE: INDEX register must be set for EP - */ -static int read_fifo(struct jz4740_ep *ep, struct jz4740_request *req) -{ - struct jz4740_udc *dev = ep->dev; - uint32_t csr; - unsigned count, is_short; - uint32_t physaddr = virt_to_phys((void *)req->req.buf); - - if (use_dma) { - uint32_t dma_count; - - /* DMA interrupt generated due to a packet less than MAXP loaded into the FIFO */ - - dma_count = usb_readl(dev, ep->reg_addr) - physaddr; - req->req.actual += dma_count; - - /* Disable interrupt and DMA */ - pio_irq_disable(ep); - usb_writel(dev, JZ_REG_UDC_CNTL2, 0); - - /* Read all bytes from this packet */ - count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); - count = read_packet(ep, req, count); - - if (count) { - /* If the last packet is greater than zero, clear OUTPKTRDY manually */ - usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY); - } - done(ep, req, 0); - - if (!list_empty(&ep->queue)) { - /* advance the request queue */ - req = list_entry(ep->queue.next, struct jz4740_request, queue); - kick_dma(ep, req); - } - - return 1; - } - - /* - * PIO mode handling starts here ... - */ - - /* make sure there's a packet in the FIFO. */ - csr = usb_readb(dev, ep->csr); - if (!(csr & USB_OUTCSR_OUTPKTRDY)) { - DEBUG("%s: Packet NOT ready!\n", __FUNCTION__); - return -EINVAL; - } - - /* read all bytes from this packet */ - count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); - - is_short = (count < ep->ep.maxpacket); - - count = read_packet(ep, req, count); - - DEBUG("read %s %02x, %d bytes%s req %p %d/%d\n", - ep->ep.name, csr, count, - is_short ? "/S" : "", req, req->req.actual, req->req.length); - - /* Clear OutPktRdy */ - usb_clearb(dev, ep->csr, USB_OUTCSR_OUTPKTRDY); - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - done(ep, req, 0); - - if (list_empty(&ep->queue)) - pio_irq_disable(ep); - return 1; - } - - /* finished that packet. the next one may be waiting... */ - return 0; -} - -/* - * done - retire a request; caller blocked irqs - * INDEX register is preserved to keep same - */ -static void done(struct jz4740_ep *ep, struct jz4740_request *req, int status) -{ - unsigned int stopped = ep->stopped; - unsigned long flags; - uint32_t index; - - DEBUG("%s, %p\n", __FUNCTION__, ep); - list_del_init(&req->queue); - - if (likely(req->req.status == -EINPROGRESS)) - req->req.status = status; - else - status = req->req.status; - - if (status && status != -ESHUTDOWN) - DEBUG("complete %s req %p stat %d len %u/%u\n", - ep->ep.name, &req->req, status, - req->req.actual, req->req.length); - - /* don't modify queue heads during completion callback */ - ep->stopped = 1; - /* Read current index (completion may modify it) */ - spin_lock_irqsave(&ep->dev->lock, flags); - index = usb_readb(ep->dev, JZ_REG_UDC_INDEX); - - req->req.complete(&ep->ep, &req->req); - - /* Restore index */ - jz_udc_set_index(ep->dev, index); - spin_unlock_irqrestore(&ep->dev->lock, flags); - ep->stopped = stopped; -} - -/** Enable EP interrupt */ -static void pio_irq_enable(struct jz4740_ep *ep) -{ - uint8_t index = ep_index(ep); - struct jz4740_udc *dev = ep->dev; - DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT"); - - if (ep_is_in(ep)) { - switch (index) { - case 1: - case 2: - usb_setw(dev, JZ_REG_UDC_INTRINE, BIT(index)); - dev->in_mask |= BIT(index); - break; - default: - DEBUG("Unknown endpoint: %d\n", index); - break; - } - } - else { - switch (index) { - case 1: - usb_setw(dev, JZ_REG_UDC_INTROUTE, BIT(index)); - dev->out_mask |= BIT(index); - break; - default: - DEBUG("Unknown endpoint: %d\n", index); - break; - } - } -} - -/** Disable EP interrupt */ -static void pio_irq_disable(struct jz4740_ep *ep) -{ - uint8_t index = ep_index(ep); - struct jz4740_udc *dev = ep->dev; - - DEBUG("%s: EP%d %s\n", __FUNCTION__, ep_index(ep), ep_is_in(ep) ? "IN": "OUT"); - - if (ep_is_in(ep)) { - switch (ep_index(ep)) { - case 1: - case 2: - usb_clearw(ep->dev, JZ_REG_UDC_INTRINE, BIT(index)); - dev->in_mask &= ~BIT(index); - break; - default: - DEBUG("Unknown endpoint: %d\n", index); - break; - } - } - else { - switch (ep_index(ep)) { - case 1: - usb_clearw(ep->dev, JZ_REG_UDC_INTROUTE, BIT(index)); - dev->out_mask &= ~BIT(index); - break; - default: - DEBUG("Unknown endpoint: %d\n", index); - break; - } - } -} - -/* - * nuke - dequeue ALL requests - */ -static void nuke(struct jz4740_ep *ep, int status) -{ - struct jz4740_request *req; - - DEBUG("%s, %p\n", __FUNCTION__, ep); - - /* Flush FIFO */ - flush(ep); - - /* called with irqs blocked */ - while (!list_empty(&ep->queue)) { - req = list_entry(ep->queue.next, struct jz4740_request, queue); - done(ep, req, status); - } - - /* Disable IRQ if EP is enabled (has descriptor) */ - if (ep->desc) - pio_irq_disable(ep); -} - -/** Flush EP FIFO - * NOTE: INDEX register must be set before this call - */ -static void flush(struct jz4740_ep *ep) -{ - DEBUG("%s: %s\n", __FUNCTION__, ep->ep.name); - - switch (ep->type) { - case ep_bulk_in: - case ep_interrupt: - usb_setb(ep->dev, ep->csr, USB_INCSR_FF); - break; - case ep_bulk_out: - usb_setb(ep->dev, ep->csr, USB_OUTCSR_FF); - break; - case ep_control: - break; - } -} - -/** - * jz4740_in_epn - handle IN interrupt - */ -static void jz4740_in_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr) -{ - uint32_t csr; - struct jz4740_ep *ep = &dev->ep[ep_idx + 1]; - struct jz4740_request *req; - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - jz_udc_set_index(dev, ep_index(ep)); - - csr = usb_readb(dev, ep->csr); - DEBUG("%s: %d, csr %x\n", __FUNCTION__, ep_idx, csr); - - if (csr & USB_INCSR_SENTSTALL) { - DEBUG("USB_INCSR_SENTSTALL\n"); - usb_clearb(dev, ep->csr, USB_INCSR_SENTSTALL); - return; - } - - if (!ep->desc) { - DEBUG("%s: NO EP DESC\n", __FUNCTION__); - return; - } - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct jz4740_request, queue); - - DEBUG("req: %p\n", req); - - if (!req) - return; - - write_fifo(ep, req); -} - -/* - * Bulk OUT (recv) - */ -static void jz4740_out_epn(struct jz4740_udc *dev, uint32_t ep_idx, uint32_t intr) -{ - struct jz4740_ep *ep = &dev->ep[ep_idx]; - struct jz4740_request *req; - - DEBUG("%s: %d\n", __FUNCTION__, ep_idx); - - jz_udc_set_index(dev, ep_index(ep)); - if (ep->desc) { - uint32_t csr; - - if (use_dma) { - /* DMA starts here ... */ - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct jz4740_request, queue); - - if (req) - read_fifo(ep, req); - return; - } - - /* - * PIO mode starts here ... - */ - - while ((csr = usb_readb(dev, ep->csr)) & - (USB_OUTCSR_OUTPKTRDY | USB_OUTCSR_SENTSTALL)) { - DEBUG("%s: %x\n", __FUNCTION__, csr); - - if (csr & USB_OUTCSR_SENTSTALL) { - DEBUG("%s: stall sent, flush fifo\n", - __FUNCTION__); - /* usb_set(USB_OUT_CSR1_FIFO_FLUSH, ep->csr1); */ - flush(ep); - } else if (csr & USB_OUTCSR_OUTPKTRDY) { - if (list_empty(&ep->queue)) - req = 0; - else - req = - list_entry(ep->queue.next, - struct jz4740_request, - queue); - - if (!req) { - DEBUG("%s: NULL REQ %d\n", - __FUNCTION__, ep_idx); - break; - } else { - read_fifo(ep, req); - } - } - } - } else { - /* Throw packet away.. */ - DEBUG("%s: ep %p ep_indx %d No descriptor?!?\n", __FUNCTION__, ep, ep_idx); - flush(ep); - } -} - -/** Halt specific EP - * Return 0 if success - * NOTE: Sets INDEX register to EP ! - */ -static int jz4740_set_halt(struct usb_ep *_ep, int value) -{ - struct jz4740_udc *dev; - struct jz4740_ep *ep; - unsigned long flags; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - ep = container_of(_ep, struct jz4740_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) { - DEBUG("%s, bad ep\n", __FUNCTION__); - return -EINVAL; - } - - dev = ep->dev; - - spin_lock_irqsave(&dev->lock, flags); - - jz_udc_select_ep(ep); - - DEBUG("%s, ep %d, val %d\n", __FUNCTION__, ep_index(ep), value); - - if (ep_index(ep) == 0) { - /* EP0 */ - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL); - } else if (ep_is_in(ep)) { - uint32_t csr = usb_readb(dev, ep->csr); - if (value && ((csr & USB_INCSR_FFNOTEMPT) - || !list_empty(&ep->queue))) { - /* - * Attempts to halt IN endpoints will fail (returning -EAGAIN) - * if any transfer requests are still queued, or if the controller - * FIFO still holds bytes that the host hasnÂ’t collected. - */ - spin_unlock_irqrestore(&dev->lock, flags); - DEBUG - ("Attempt to halt IN endpoint failed (returning -EAGAIN) %d %d\n", - (csr & USB_INCSR_FFNOTEMPT), - !list_empty(&ep->queue)); - return -EAGAIN; - } - flush(ep); - if (value) { - usb_setb(dev, ep->csr, USB_INCSR_SENDSTALL); - } - else { - usb_clearb(dev, ep->csr, USB_INCSR_SENDSTALL); - usb_setb(dev, ep->csr, USB_INCSR_CDT); - } - } else { - - flush(ep); - if (value) { - usb_setb(dev, ep->csr, USB_OUTCSR_SENDSTALL); - } - else { - usb_clearb(dev, ep->csr, USB_OUTCSR_SENDSTALL); - usb_setb(dev, ep->csr, USB_OUTCSR_CDT); - } - } - - if (value) { - ep->stopped = 1; - } else { - ep->stopped = 0; - } - - spin_unlock_irqrestore(&dev->lock, flags); - - DEBUG("%s %s halted\n", _ep->name, value == 0 ? "NOT" : "IS"); - - return 0; -} - - -static int jz4740_ep_enable(struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) -{ - struct jz4740_ep *ep; - struct jz4740_udc *dev; - unsigned long flags; - uint32_t max, csrh = 0; - - DEBUG("%s: trying to enable %s\n", __FUNCTION__, _ep->name); - - if (!_ep || !desc) - return -EINVAL; - - ep = container_of(_ep, struct jz4740_ep, ep); - if (ep->desc || ep->type == ep_control - || desc->bDescriptorType != USB_DT_ENDPOINT - || ep->bEndpointAddress != desc->bEndpointAddress) { - DEBUG("%s, bad ep or descriptor\n", __FUNCTION__); - return -EINVAL; - } - - /* xfer types must match, except that interrupt ~= bulk */ - if (ep->bmAttributes != desc->bmAttributes - && ep->bmAttributes != USB_ENDPOINT_XFER_BULK - && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { - DEBUG("%s, %s type mismatch\n", __FUNCTION__, _ep->name); - return -EINVAL; - } - - dev = ep->dev; - if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) { - DEBUG("%s, bogus device state\n", __FUNCTION__); - return -ESHUTDOWN; - } - - max = le16_to_cpu(desc->wMaxPacketSize); - - spin_lock_irqsave(&ep->dev->lock, flags); - - /* Configure the endpoint */ - jz_udc_set_index(dev, desc->bEndpointAddress & 0x0F); - if (ep_is_in(ep)) { - usb_writew(dev, JZ_REG_UDC_INMAXP, max); - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_BULK: - case USB_ENDPOINT_XFER_INT: - csrh &= ~USB_INCSRH_ISO; - break; - case USB_ENDPOINT_XFER_ISOC: - csrh |= USB_INCSRH_ISO; - break; - } - usb_writeb(dev, JZ_REG_UDC_INCSRH, csrh); - } - else { - usb_writew(dev, JZ_REG_UDC_OUTMAXP, max); - switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { - case USB_ENDPOINT_XFER_BULK: - csrh &= ~USB_OUTCSRH_ISO; - break; - case USB_ENDPOINT_XFER_INT: - csrh &= ~USB_OUTCSRH_ISO; - csrh |= USB_OUTCSRH_DNYT; - break; - case USB_ENDPOINT_XFER_ISOC: - csrh |= USB_OUTCSRH_ISO; - break; - } - usb_writeb(dev, JZ_REG_UDC_OUTCSRH, csrh); - } - - - ep->stopped = 0; - ep->desc = desc; - ep->pio_irqs = 0; - ep->ep.maxpacket = max; - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - /* Reset halt state (does flush) */ - jz4740_set_halt(_ep, 0); - - DEBUG("%s: enabled %s\n", __FUNCTION__, _ep->name); - - return 0; -} - -/** Disable EP - * NOTE: Sets INDEX register - */ -static int jz4740_ep_disable(struct usb_ep *_ep) -{ - struct jz4740_ep *ep; - unsigned long flags; - - DEBUG("%s, %p\n", __FUNCTION__, _ep); - - ep = container_of(_ep, struct jz4740_ep, ep); - if (!_ep || !ep->desc) { - DEBUG("%s, %s not enabled\n", __FUNCTION__, - _ep ? ep->ep.name : NULL); - return -EINVAL; - } - - spin_lock_irqsave(&ep->dev->lock, flags); - - jz_udc_select_ep(ep); - - /* Nuke all pending requests (does flush) */ - nuke(ep, -ESHUTDOWN); - - /* Disable ep IRQ */ - pio_irq_disable(ep); - - ep->desc = 0; - ep->stopped = 1; - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - DEBUG("%s: disabled %s\n", __FUNCTION__, _ep->name); - return 0; -} - -static struct usb_request *jz4740_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) -{ - struct jz4740_request *req; - - DEBUG("%s, %p\n", __FUNCTION__, ep); - - req = kzalloc(sizeof(*req), gfp_flags); - if (!req) - return 0; - - INIT_LIST_HEAD(&req->queue); - - return &req->req; -} - -static void jz4740_free_request(struct usb_ep *ep, struct usb_request *_req) -{ - struct jz4740_request *req; - - DEBUG("%s, %p\n", __FUNCTION__, ep); - - req = container_of(_req, struct jz4740_request, req); - WARN_ON(!list_empty(&req->queue)); - kfree(req); -} - -/*--------------------------------------------------------------------*/ - -/** Queue one request - * Kickstart transfer if needed - * NOTE: Sets INDEX register - */ -static int jz4740_queue(struct usb_ep *_ep, struct usb_request *_req, - gfp_t gfp_flags) -{ - struct jz4740_request *req; - struct jz4740_ep *ep; - struct jz4740_udc *dev; - unsigned long flags; - - DEBUG("%s, %p\n", __FUNCTION__, _ep); - - req = container_of(_req, struct jz4740_request, req); - if (unlikely - (!_req || !_req->complete || !_req->buf - || !list_empty(&req->queue))) { - DEBUG("%s, bad params\n", __FUNCTION__); - return -EINVAL; - } - - ep = container_of(_ep, struct jz4740_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->type != ep_control))) { - DEBUG("%s, bad ep\n", __FUNCTION__); - return -EINVAL; - } - - dev = ep->dev; - if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) { - DEBUG("%s, bogus device state %p\n", __FUNCTION__, dev->driver); - return -ESHUTDOWN; - } - - DEBUG("%s queue req %p, len %d buf %p\n", _ep->name, _req, _req->length, - _req->buf); - - spin_lock_irqsave(&dev->lock, flags); - - _req->status = -EINPROGRESS; - _req->actual = 0; - - /* kickstart this i/o queue? */ - DEBUG("Add to %d Q %d %d\n", ep_index(ep), list_empty(&ep->queue), - ep->stopped); - if (list_empty(&ep->queue) && likely(!ep->stopped)) { - uint32_t csr; - - if (unlikely(ep_index(ep) == 0)) { - /* EP0 */ - list_add_tail(&req->queue, &ep->queue); - jz4740_ep0_kick(dev, ep); - req = 0; - } else if (use_dma) { - /* DMA */ - kick_dma(ep, req); - } - /* PIO */ - else if (ep_is_in(ep)) { - /* EP1 & EP2 */ - jz_udc_set_index(dev, ep_index(ep)); - csr = usb_readb(dev, ep->csr); - pio_irq_enable(ep); - if (!(csr & USB_INCSR_FFNOTEMPT)) { - if (write_fifo(ep, req) == 1) - req = 0; - } - } else { - /* EP1 */ - jz_udc_set_index(dev, ep_index(ep)); - csr = usb_readb(dev, ep->csr); - pio_irq_enable(ep); - if (csr & USB_OUTCSR_OUTPKTRDY) { - if (read_fifo(ep, req) == 1) - req = 0; - } - } - } - - /* pio or dma irq handler advances the queue. */ - if (likely(req != 0)) - list_add_tail(&req->queue, &ep->queue); - - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -/* dequeue JUST ONE request */ -static int jz4740_dequeue(struct usb_ep *_ep, struct usb_request *_req) -{ - struct jz4740_ep *ep; - struct jz4740_request *req; - unsigned long flags; - - DEBUG("%s, %p\n", __FUNCTION__, _ep); - - ep = container_of(_ep, struct jz4740_ep, ep); - if (!_ep || ep->type == ep_control) - return -EINVAL; - - spin_lock_irqsave(&ep->dev->lock, flags); - - /* make sure it's actually queued on this endpoint */ - list_for_each_entry(req, &ep->queue, queue) { - if (&req->req == _req) - break; - } - if (&req->req != _req) { - spin_unlock_irqrestore(&ep->dev->lock, flags); - return -EINVAL; - } - done(ep, req, -ECONNRESET); - - spin_unlock_irqrestore(&ep->dev->lock, flags); - return 0; -} - -/** Return bytes in EP FIFO - * NOTE: Sets INDEX register to EP - */ -static int jz4740_fifo_status(struct usb_ep *_ep) -{ - uint32_t csr; - int count = 0; - struct jz4740_ep *ep; - unsigned long flags; - - ep = container_of(_ep, struct jz4740_ep, ep); - if (!_ep) { - DEBUG("%s, bad ep\n", __FUNCTION__); - return -ENODEV; - } - - DEBUG("%s, %d\n", __FUNCTION__, ep_index(ep)); - - /* LPD can't report unclaimed bytes from IN fifos */ - if (ep_is_in(ep)) - return -EOPNOTSUPP; - - spin_lock_irqsave(&ep->dev->lock, flags); - jz_udc_set_index(ep->dev, ep_index(ep)); - - csr = usb_readb(ep->dev, ep->csr); - if (ep->dev->gadget.speed != USB_SPEED_UNKNOWN || - csr & 0x1) { - count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT); - } - - spin_unlock_irqrestore(&ep->dev->lock, flags); - - return count; -} - -/** Flush EP FIFO - * NOTE: Sets INDEX register to EP - */ -static void jz4740_fifo_flush(struct usb_ep *_ep) -{ - struct jz4740_ep *ep; - unsigned long flags; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - ep = container_of(_ep, struct jz4740_ep, ep); - if (unlikely(!_ep || (!ep->desc && ep->type == ep_control))) { - DEBUG("%s, bad ep\n", __FUNCTION__); - return; - } - - spin_lock_irqsave(&ep->dev->lock, flags); - - jz_udc_set_index(ep->dev, ep_index(ep)); - flush(ep); - - spin_unlock_irqrestore(&ep->dev->lock, flags); -} - -/****************************************************************/ -/* End Point 0 related functions */ -/****************************************************************/ - -/* return: 0 = still running, 1 = completed, negative = errno */ -static int write_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req) -{ - uint32_t max; - unsigned count; - int is_last; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - max = ep_maxpacket(ep); - - count = write_packet(ep, req, max); - - /* last packet is usually short (or a zlp) */ - if (unlikely(count != max)) - is_last = 1; - else { - if (likely(req->req.length != req->req.actual) || req->req.zero) - is_last = 0; - else - is_last = 1; - } - - DEBUG_EP0("%s: wrote %s %d bytes%s %d left %p\n", __FUNCTION__, - ep->ep.name, count, - is_last ? "/L" : "", req->req.length - req->req.actual, req); - - /* requests complete when all IN data is in the FIFO */ - if (is_last) { - done(ep, req, 0); - return 1; - } - - return 0; -} - -static inline int jz4740_fifo_read(struct jz4740_ep *ep, - unsigned char *cp, int max) -{ - int bytes; - int count = usb_readw(ep->dev, JZ_REG_UDC_OUTCOUNT); - - if (count > max) - count = max; - bytes = count; - while (count--) - *cp++ = usb_readb(ep->dev, ep->fifo); - - return bytes; -} - -static inline void jz4740_fifo_write(struct jz4740_ep *ep, - unsigned char *cp, int count) -{ - DEBUG("fifo_write: %d %d\n", ep_index(ep), count); - while (count--) - usb_writeb(ep->dev, ep->fifo, *cp++); -} - -static int read_fifo_ep0(struct jz4740_ep *ep, struct jz4740_request *req) -{ - struct jz4740_udc *dev = ep->dev; - uint32_t csr; - uint8_t *buf; - unsigned bufferspace, count, is_short; - - DEBUG_EP0("%s\n", __FUNCTION__); - - csr = usb_readb(dev, JZ_REG_UDC_CSR0); - if (!(csr & USB_CSR0_OUTPKTRDY)) - return 0; - - buf = req->req.buf + req->req.actual; - prefetchw(buf); - bufferspace = req->req.length - req->req.actual; - - /* read all bytes from this packet */ - if (likely(csr & USB_CSR0_OUTPKTRDY)) { - count = usb_readw(dev, JZ_REG_UDC_OUTCOUNT); - req->req.actual += min(count, bufferspace); - } else /* zlp */ - count = 0; - - is_short = (count < ep->ep.maxpacket); - DEBUG_EP0("read %s %02x, %d bytes%s req %p %d/%d\n", - ep->ep.name, csr, count, - is_short ? "/S" : "", req, req->req.actual, req->req.length); - - while (likely(count-- != 0)) { - uint8_t byte = (uint8_t)usb_readl(dev, ep->fifo); - - if (unlikely(bufferspace == 0)) { - /* this happens when the driver's buffer - * is smaller than what the host sent. - * discard the extra data. - */ - if (req->req.status != -EOVERFLOW) - DEBUG_EP0("%s overflow %d\n", ep->ep.name, - count); - req->req.status = -EOVERFLOW; - } else { - *buf++ = byte; - bufferspace--; - } - } - - /* completion */ - if (is_short || req->req.actual == req->req.length) { - done(ep, req, 0); - return 1; - } - - /* finished that packet. the next one may be waiting... */ - return 0; -} - -/** - * udc_set_address - set the USB address for this device - * @address: - * - * Called from control endpoint function after it decodes a set address setup packet. - */ -static void udc_set_address(struct jz4740_udc *dev, unsigned char address) -{ - DEBUG_EP0("%s: %d\n", __FUNCTION__, address); - - dev->usb_address = address; - usb_writeb(dev, JZ_REG_UDC_FADDR, address); -} - -/* - * DATA_STATE_RECV (USB_CSR0_OUTPKTRDY) - * - if error - * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits - * - else - * set USB_CSR0_SVDOUTPKTRDY bit - if last set USB_CSR0_DATAEND bit - */ -static void jz4740_ep0_out(struct jz4740_udc *dev, uint32_t csr, int kickstart) -{ - struct jz4740_request *req; - struct jz4740_ep *ep = &dev->ep[0]; - int ret; - - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct jz4740_request, queue); - - if (req) { - if (req->req.length == 0) { - DEBUG_EP0("ZERO LENGTH OUT!\n"); - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); - dev->ep0state = WAIT_FOR_SETUP; - return; - } else if (kickstart) { - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY)); - return; - } - ret = read_fifo_ep0(ep, req); - if (ret) { - /* Done! */ - DEBUG_EP0("%s: finished, waiting for status\n", - __FUNCTION__); - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); - dev->ep0state = WAIT_FOR_SETUP; - } else { - /* Not done yet.. */ - DEBUG_EP0("%s: not finished\n", __FUNCTION__); - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); - } - } else { - DEBUG_EP0("NO REQ??!\n"); - } -} - -/* - * DATA_STATE_XMIT - */ -static int jz4740_ep0_in(struct jz4740_udc *dev, uint32_t csr) -{ - struct jz4740_request *req; - struct jz4740_ep *ep = &dev->ep[0]; - int ret, need_zlp = 0; - - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); - - if (list_empty(&ep->queue)) - req = 0; - else - req = list_entry(ep->queue.next, struct jz4740_request, queue); - - if (!req) { - DEBUG_EP0("%s: NULL REQ\n", __FUNCTION__); - return 0; - } - - if (req->req.length == 0) { - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); - dev->ep0state = WAIT_FOR_SETUP; - return 1; - } - - if (req->req.length - req->req.actual == EP0_MAXPACKETSIZE) { - /* Next write will end with the packet size, */ - /* so we need zero-length-packet */ - need_zlp = 1; - } - - ret = write_fifo_ep0(ep, req); - - if (ret == 1 && !need_zlp) { - /* Last packet */ - DEBUG_EP0("%s: finished, waiting for status\n", __FUNCTION__); - - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); - dev->ep0state = WAIT_FOR_SETUP; - } else { - DEBUG_EP0("%s: not finished\n", __FUNCTION__); - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY); - } - - if (need_zlp) { - DEBUG_EP0("%s: Need ZLP!\n", __FUNCTION__); - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_INPKTRDY); - dev->ep0state = DATA_STATE_NEED_ZLP; - } - - return 1; -} - -static int jz4740_handle_get_status(struct jz4740_udc *dev, - struct usb_ctrlrequest *ctrl) -{ - struct jz4740_ep *ep0 = &dev->ep[0]; - struct jz4740_ep *qep; - int reqtype = (ctrl->bRequestType & USB_RECIP_MASK); - uint16_t val = 0; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - - if (reqtype == USB_RECIP_INTERFACE) { - /* This is not supported. - * And according to the USB spec, this one does nothing.. - * Just return 0 - */ - DEBUG_SETUP("GET_STATUS: USB_RECIP_INTERFACE\n"); - } else if (reqtype == USB_RECIP_DEVICE) { - DEBUG_SETUP("GET_STATUS: USB_RECIP_DEVICE\n"); - val |= (1 << 0); /* Self powered */ - /*val |= (1<<1); *//* Remote wakeup */ - } else if (reqtype == USB_RECIP_ENDPOINT) { - int ep_num = (ctrl->wIndex & ~USB_DIR_IN); - - DEBUG_SETUP - ("GET_STATUS: USB_RECIP_ENDPOINT (%d), ctrl->wLength = %d\n", - ep_num, ctrl->wLength); - - if (ctrl->wLength > 2 || ep_num > 3) - return -EOPNOTSUPP; - - qep = &dev->ep[ep_num]; - if (ep_is_in(qep) != ((ctrl->wIndex & USB_DIR_IN) ? 1 : 0) - && ep_index(qep) != 0) { - return -EOPNOTSUPP; - } - - jz_udc_set_index(dev, ep_index(qep)); - - /* Return status on next IN token */ - switch (qep->type) { - case ep_control: - val = - (usb_readb(dev, qep->csr) & USB_CSR0_SENDSTALL) == - USB_CSR0_SENDSTALL; - break; - case ep_bulk_in: - case ep_interrupt: - val = - (usb_readb(dev, qep->csr) & USB_INCSR_SENDSTALL) == - USB_INCSR_SENDSTALL; - break; - case ep_bulk_out: - val = - (usb_readb(dev, qep->csr) & USB_OUTCSR_SENDSTALL) == - USB_OUTCSR_SENDSTALL; - break; - } - - /* Back to EP0 index */ - jz_udc_set_index(dev, 0); - - DEBUG_SETUP("GET_STATUS, ep: %d (%x), val = %d\n", ep_num, - ctrl->wIndex, val); - } else { - DEBUG_SETUP("Unknown REQ TYPE: %d\n", reqtype); - return -EOPNOTSUPP; - } - - /* Clear "out packet ready" */ - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); - /* Put status to FIFO */ - jz4740_fifo_write(ep0, (uint8_t *)&val, sizeof(val)); - /* Issue "In packet ready" */ - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); - - return 0; -} - -/* - * WAIT_FOR_SETUP (OUTPKTRDY) - * - read data packet from EP0 FIFO - * - decode command - * - if error - * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL bits - * - else - * set USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND bits - */ -static void jz4740_ep0_setup(struct jz4740_udc *dev, uint32_t csr) -{ - struct jz4740_ep *ep = &dev->ep[0]; - struct usb_ctrlrequest ctrl; - int i; - - DEBUG_SETUP("%s: %x\n", __FUNCTION__, csr); - - /* Nuke all previous transfers */ - nuke(ep, -EPROTO); - - /* read control req from fifo (8 bytes) */ - jz4740_fifo_read(ep, (unsigned char *)&ctrl, 8); - - DEBUG_SETUP("SETUP %02x.%02x v%04x i%04x l%04x\n", - ctrl.bRequestType, ctrl.bRequest, - ctrl.wValue, ctrl.wIndex, ctrl.wLength); - - /* Set direction of EP0 */ - if (likely(ctrl.bRequestType & USB_DIR_IN)) { - ep->bEndpointAddress |= USB_DIR_IN; - } else { - ep->bEndpointAddress &= ~USB_DIR_IN; - } - - /* Handle some SETUP packets ourselves */ - switch (ctrl.bRequest) { - case USB_REQ_SET_ADDRESS: - if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) - break; - - DEBUG_SETUP("USB_REQ_SET_ADDRESS (%d)\n", ctrl.wValue); - udc_set_address(dev, ctrl.wValue); - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); - return; - - case USB_REQ_SET_CONFIGURATION: - if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) - break; - - DEBUG_SETUP("USB_REQ_SET_CONFIGURATION (%d)\n", ctrl.wValue); -/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/ - - /* Enable RESUME and SUSPEND interrupts */ - usb_setb(dev, JZ_REG_UDC_INTRUSBE, (USB_INTR_RESUME | USB_INTR_SUSPEND)); - break; - - case USB_REQ_SET_INTERFACE: - if (ctrl.bRequestType != (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) - break; - - DEBUG_SETUP("USB_REQ_SET_INTERFACE (%d)\n", ctrl.wValue); -/* usb_setb(JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND));*/ - break; - - case USB_REQ_GET_STATUS: - if (jz4740_handle_get_status(dev, &ctrl) == 0) - return; - - case USB_REQ_CLEAR_FEATURE: - case USB_REQ_SET_FEATURE: - if (ctrl.bRequestType == USB_RECIP_ENDPOINT) { - struct jz4740_ep *qep; - int ep_num = (ctrl.wIndex & 0x0f); - - /* Support only HALT feature */ - if (ctrl.wValue != 0 || ctrl.wLength != 0 - || ep_num > 3 || ep_num < 1) - break; - - qep = &dev->ep[ep_num]; - spin_unlock(&dev->lock); - if (ctrl.bRequest == USB_REQ_SET_FEATURE) { - DEBUG_SETUP("SET_FEATURE (%d)\n", - ep_num); - jz4740_set_halt(&qep->ep, 1); - } else { - DEBUG_SETUP("CLR_FEATURE (%d)\n", - ep_num); - jz4740_set_halt(&qep->ep, 0); - } - spin_lock(&dev->lock); - - jz_udc_set_index(dev, 0); - - /* Reply with a ZLP on next IN token */ - usb_setb(dev, JZ_REG_UDC_CSR0, - (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND)); - return; - } - break; - - default: - break; - } - - /* gadget drivers see class/vendor specific requests, - * {SET,GET}_{INTERFACE,DESCRIPTOR,CONFIGURATION}, - * and more. - */ - if (dev->driver) { - /* device-2-host (IN) or no data setup command, process immediately */ - spin_unlock(&dev->lock); - - i = dev->driver->setup(&dev->gadget, &ctrl); - spin_lock(&dev->lock); - - if (unlikely(i < 0)) { - /* setup processing failed, force stall */ - DEBUG_SETUP - (" --> ERROR: gadget setup FAILED (stalling), setup returned %d\n", - i); - jz_udc_set_index(dev, 0); - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND | USB_CSR0_SENDSTALL)); - - /* ep->stopped = 1; */ - dev->ep0state = WAIT_FOR_SETUP; - } - else { - DEBUG_SETUP("gadget driver setup ok (%d)\n", ctrl.wLength); -/* if (!ctrl.wLength) { - usb_setb(JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); - }*/ - } - } -} - -/* - * DATA_STATE_NEED_ZLP - */ -static void jz4740_ep0_in_zlp(struct jz4740_udc *dev, uint32_t csr) -{ - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); - - usb_setb(dev, JZ_REG_UDC_CSR0, (USB_CSR0_INPKTRDY | USB_CSR0_DATAEND)); - dev->ep0state = WAIT_FOR_SETUP; -} - -/* - * handle ep0 interrupt - */ -static void jz4740_handle_ep0(struct jz4740_udc *dev, uint32_t intr) -{ - struct jz4740_ep *ep = &dev->ep[0]; - uint32_t csr; - - DEBUG("%s:%s[%d]\n", __FILE__, __func__, __LINE__); - /* Set index 0 */ - jz_udc_set_index(dev, 0); - csr = usb_readb(dev, JZ_REG_UDC_CSR0); - - DEBUG_EP0("%s: csr = %x state = \n", __FUNCTION__, csr);//, state_names[dev->ep0state]); - - /* - * if SENT_STALL is set - * - clear the SENT_STALL bit - */ - if (csr & USB_CSR0_SENTSTALL) { - DEBUG_EP0("%s: USB_CSR0_SENTSTALL is set: %x\n", __FUNCTION__, csr); - usb_clearb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SENDSTALL | USB_CSR0_SENTSTALL); - nuke(ep, -ECONNABORTED); - dev->ep0state = WAIT_FOR_SETUP; - return; - } - - /* - * if a transfer is in progress && INPKTRDY and OUTPKTRDY are clear - * - fill EP0 FIFO - * - if last packet - * - set IN_PKT_RDY | DATA_END - * - else - * set IN_PKT_RDY - */ - if (!(csr & (USB_CSR0_INPKTRDY | USB_CSR0_OUTPKTRDY))) { - DEBUG_EP0("%s: INPKTRDY and OUTPKTRDY are clear\n", - __FUNCTION__); - - switch (dev->ep0state) { - case DATA_STATE_XMIT: - DEBUG_EP0("continue with DATA_STATE_XMIT\n"); - jz4740_ep0_in(dev, csr); - return; - case DATA_STATE_NEED_ZLP: - DEBUG_EP0("continue with DATA_STATE_NEED_ZLP\n"); - jz4740_ep0_in_zlp(dev, csr); - return; - default: - /* Stall? */ -// DEBUG_EP0("Odd state!! state = %s\n", -// state_names[dev->ep0state]); - dev->ep0state = WAIT_FOR_SETUP; - /* nuke(ep, 0); */ - /* usb_setb(ep->csr, USB_CSR0_SENDSTALL); */ -// break; - return; - } - } - - /* - * if SETUPEND is set - * - abort the last transfer - * - set SERVICED_SETUP_END_BIT - */ - if (csr & USB_CSR0_SETUPEND) { - DEBUG_EP0("%s: USB_CSR0_SETUPEND is set: %x\n", __FUNCTION__, csr); - - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDSETUPEND); - nuke(ep, 0); - dev->ep0state = WAIT_FOR_SETUP; - } - - /* - * if USB_CSR0_OUTPKTRDY is set - * - read data packet from EP0 FIFO - * - decode command - * - if error - * set SVDOUTPKTRDY | DATAEND | SENDSTALL bits - * - else - * set SVDOUTPKTRDY | DATAEND bits - */ - if (csr & USB_CSR0_OUTPKTRDY) { - - DEBUG_EP0("%s: EP0_OUT_PKT_RDY is set: %x\n", __FUNCTION__, - csr); - - switch (dev->ep0state) { - case WAIT_FOR_SETUP: - DEBUG_EP0("WAIT_FOR_SETUP\n"); - jz4740_ep0_setup(dev, csr); - break; - - case DATA_STATE_RECV: - DEBUG_EP0("DATA_STATE_RECV\n"); - jz4740_ep0_out(dev, csr, 0); - break; - - default: - /* send stall? */ - DEBUG_EP0("strange state!! 2. send stall? state = %d\n", - dev->ep0state); - break; - } - } -} - -static void jz4740_ep0_kick(struct jz4740_udc *dev, struct jz4740_ep *ep) -{ - uint32_t csr; - - jz_udc_set_index(dev, 0); - - DEBUG_EP0("%s: %x\n", __FUNCTION__, csr); - - /* Clear "out packet ready" */ - - if (ep_is_in(ep)) { - usb_setb(dev, JZ_REG_UDC_CSR0, USB_CSR0_SVDOUTPKTRDY); - csr = usb_readb(dev, JZ_REG_UDC_CSR0); - dev->ep0state = DATA_STATE_XMIT; - jz4740_ep0_in(dev, csr); - } else { - csr = usb_readb(dev, JZ_REG_UDC_CSR0); - dev->ep0state = DATA_STATE_RECV; - jz4740_ep0_out(dev, csr, 1); - } -} - -/** Handle USB RESET interrupt - */ -static void jz4740_reset_irq(struct jz4740_udc *dev) -{ - dev->gadget.speed = (usb_readb(dev, JZ_REG_UDC_POWER) & USB_POWER_HSMODE) ? - USB_SPEED_HIGH : USB_SPEED_FULL; - - DEBUG_SETUP("%s: address = %d, speed = %s\n", __FUNCTION__, dev->usb_address, - (dev->gadget.speed == USB_SPEED_HIGH) ? "HIGH":"FULL" ); -} - -/* - * jz4740 usb device interrupt handler. - */ -static irqreturn_t jz4740_udc_irq(int irq, void *_dev) -{ - struct jz4740_udc *dev = _dev; - uint8_t index; - - uint32_t intr_usb = usb_readb(dev, JZ_REG_UDC_INTRUSB) & 0x7; /* mask SOF */ - uint32_t intr_in = usb_readw(dev, JZ_REG_UDC_INTRIN); - uint32_t intr_out = usb_readw(dev, JZ_REG_UDC_INTROUT); - uint32_t intr_dma = usb_readb(dev, JZ_REG_UDC_INTR); - - if (!intr_usb && !intr_in && !intr_out && !intr_dma) - return IRQ_HANDLED; - - - DEBUG("intr_out=%x intr_in=%x intr_usb=%x\n", - intr_out, intr_in, intr_usb); - - spin_lock(&dev->lock); - index = usb_readb(dev, JZ_REG_UDC_INDEX); - - /* Check for resume from suspend mode */ - if ((intr_usb & USB_INTR_RESUME) && - (usb_readb(dev, JZ_REG_UDC_INTRUSBE) & USB_INTR_RESUME)) { - DEBUG("USB resume\n"); - dev->driver->resume(&dev->gadget); /* We have suspend(), so we must have resume() too. */ - } - - /* Check for system interrupts */ - if (intr_usb & USB_INTR_RESET) { - DEBUG("USB reset\n"); - jz4740_reset_irq(dev); - } - - /* Check for endpoint 0 interrupt */ - if (intr_in & USB_INTR_EP0) { - DEBUG("USB_INTR_EP0 (control)\n"); - jz4740_handle_ep0(dev, intr_in); - } - - /* Check for Bulk-IN DMA interrupt */ - if (intr_dma & 0x1) { - int ep_num; - struct jz4740_ep *ep; - ep_num = (usb_readl(dev, JZ_REG_UDC_CNTL1) >> 4) & 0xf; - ep = &dev->ep[ep_num + 1]; - jz_udc_set_index(dev, ep_num); - usb_setb(dev, ep->csr, USB_INCSR_INPKTRDY); -/* jz4740_in_epn(dev, ep_num, intr_in);*/ - } - - /* Check for Bulk-OUT DMA interrupt */ - if (intr_dma & 0x2) { - int ep_num; - ep_num = (usb_readl(dev, JZ_REG_UDC_CNTL2) >> 4) & 0xf; - jz4740_out_epn(dev, ep_num, intr_out); - } - - /* Check for each configured endpoint interrupt */ - if (intr_in & USB_INTR_INEP1) { - DEBUG("USB_INTR_INEP1\n"); - jz4740_in_epn(dev, 1, intr_in); - } - - if (intr_in & USB_INTR_INEP2) { - DEBUG("USB_INTR_INEP2\n"); - jz4740_in_epn(dev, 2, intr_in); - } - - if (intr_out & USB_INTR_OUTEP1) { - DEBUG("USB_INTR_OUTEP1\n"); - jz4740_out_epn(dev, 1, intr_out); - } - - /* Check for suspend mode */ - if ((intr_usb & USB_INTR_SUSPEND) && - (usb_readb(dev, JZ_REG_UDC_INTRUSBE) & USB_INTR_SUSPEND)) { - DEBUG("USB suspend\n"); - dev->driver->suspend(&dev->gadget); - /* Host unloaded from us, can do something, such as flushing - the NAND block cache etc. */ - } - - jz_udc_set_index(dev, index); - - spin_unlock(&dev->lock); - - return IRQ_HANDLED; -} - - - -/*-------------------------------------------------------------------------*/ - -/* Common functions - Added by River */ -static struct jz4740_udc udc_dev; - -static inline struct jz4740_udc *gadget_to_udc(struct usb_gadget *gadget) -{ - return container_of(gadget, struct jz4740_udc, gadget); -} -/* End added */ - -static int jz4740_udc_get_frame(struct usb_gadget *_gadget) -{ - DEBUG("%s, %p\n", __FUNCTION__, _gadget); - return usb_readw(gadget_to_udc(_gadget), JZ_REG_UDC_FRAME); -} - -static int jz4740_udc_wakeup(struct usb_gadget *_gadget) -{ - /* host may not have enabled remote wakeup */ - /*if ((UDCCS0 & UDCCS0_DRWF) == 0) - return -EHOSTUNREACH; - udc_set_mask_UDCCR(UDCCR_RSM); */ - return -ENOTSUPP; -} - -static int jz4740_udc_pullup(struct usb_gadget *_gadget, int on) -{ - struct jz4740_udc *udc = gadget_to_udc(_gadget); - unsigned long flags; - - local_irq_save(flags); - - if (on) { - udc->state = UDC_STATE_ENABLE; - udc_enable(udc); - } else { - udc->state = UDC_STATE_DISABLE; - udc_disable(udc); - } - - local_irq_restore(flags); - - return 0; -} - - -static const struct usb_gadget_ops jz4740_udc_ops = { - .get_frame = jz4740_udc_get_frame, - .wakeup = jz4740_udc_wakeup, - .pullup = jz4740_udc_pullup, - /* current versions must always be self-powered */ -}; - -static struct usb_ep_ops jz4740_ep_ops = { - .enable = jz4740_ep_enable, - .disable = jz4740_ep_disable, - - .alloc_request = jz4740_alloc_request, - .free_request = jz4740_free_request, - - .queue = jz4740_queue, - .dequeue = jz4740_dequeue, - - .set_halt = jz4740_set_halt, - .fifo_status = jz4740_fifo_status, - .fifo_flush = jz4740_fifo_flush, -}; - - -/*-------------------------------------------------------------------------*/ - -static struct jz4740_udc udc_dev = { - .usb_address = 0, - .gadget = { - .ops = &jz4740_udc_ops, - .ep0 = &udc_dev.ep[0].ep, - .name = "jz-udc", - .dev = { - .init_name = "gadget", - }, - }, - - /* control endpoint */ - .ep[0] = { - .ep = { - .name = "ep0", - .ops = &jz4740_ep_ops, - .maxpacket = EP0_MAXPACKETSIZE, - }, - .dev = &udc_dev, - - .bEndpointAddress = 0, - .bmAttributes = 0, - - .type = ep_control, - .fifo = JZ_REG_UDC_EP_FIFO(0), - .csr = JZ_REG_UDC_CSR0, - }, - - /* bulk out endpoint */ - .ep[1] = { - .ep = { - .name = "ep1out-bulk", - .ops = &jz4740_ep_ops, - .maxpacket = EPBULK_MAXPACKETSIZE, - }, - .dev = &udc_dev, - - .bEndpointAddress = 1, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - - .type = ep_bulk_out, - .fifo = JZ_REG_UDC_EP_FIFO(1), - .csr = JZ_REG_UDC_OUTCSR, - }, - - /* bulk in endpoint */ - .ep[2] = { - .ep = { - .name = "ep1in-bulk", - .ops = &jz4740_ep_ops, - .maxpacket = EPBULK_MAXPACKETSIZE, - }, - .dev = &udc_dev, - - .bEndpointAddress = 1 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - - .type = ep_bulk_in, - .fifo = JZ_REG_UDC_EP_FIFO(1), - .csr = JZ_REG_UDC_INCSR, - }, - - /* interrupt in endpoint */ - .ep[3] = { - .ep = { - .name = "ep2in-int", - .ops = &jz4740_ep_ops, - .maxpacket = EPINTR_MAXPACKETSIZE, - }, - .dev = &udc_dev, - - .bEndpointAddress = 2 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - - .type = ep_interrupt, - .fifo = JZ_REG_UDC_EP_FIFO(2), - .csr = JZ_REG_UDC_INCSR, - }, -}; - -static void gadget_release(struct device *_dev) -{ -} - - -static int jz4740_udc_probe(struct platform_device *pdev) -{ - struct jz4740_udc *dev = &udc_dev; - int ret; - - spin_lock_init(&dev->lock); - the_controller = dev; - - dev->dev = &pdev->dev; - dev_set_name(&dev->gadget.dev, "gadget"); - dev->gadget.dev.parent = &pdev->dev; - dev->gadget.dev.dma_mask = pdev->dev.dma_mask; - dev->gadget.dev.release = gadget_release; - - ret = device_register(&dev->gadget.dev); - if (ret) - return ret; - - dev->clk = clk_get(&pdev->dev, "udc"); - if (IS_ERR(dev->clk)) { - ret = PTR_ERR(dev->clk); - dev_err(&pdev->dev, "Failed to get udc clock: %d\n", ret); - goto err_device_unregister; - } - - platform_set_drvdata(pdev, dev); - - dev->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!dev->mem) { - ret = -ENOENT; - dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); - goto err_clk_put; - } - - dev->mem = request_mem_region(dev->mem->start, resource_size(dev->mem), pdev->name); - - if (!dev->mem) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to request mmio memory region\n"); - goto err_device_unregister; - } - - dev->base = ioremap(dev->mem->start, resource_size(dev->mem)); - - if (!dev->base) { - ret = -EBUSY; - dev_err(&pdev->dev, "Failed to ioremap mmio memory\n"); - goto err_release_mem_region; - } - - dev->irq = platform_get_irq(pdev, 0); - - ret = request_irq(dev->irq, jz4740_udc_irq, IRQF_DISABLED, - pdev->name, dev); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); - goto err_iounmap; - } - - udc_disable(dev); - udc_reinit(dev); - - return 0; - -err_iounmap: - iounmap(dev->base); -err_release_mem_region: - release_mem_region(dev->mem->start, resource_size(dev->mem)); -err_clk_put: - clk_put(dev->clk); -err_device_unregister: - device_unregister(&dev->gadget.dev); - platform_set_drvdata(pdev, NULL); - - the_controller = 0; - - return ret; -} - -static int jz4740_udc_remove(struct platform_device *pdev) -{ - struct jz4740_udc *dev = platform_get_drvdata(pdev); - - if (dev->driver) - return -EBUSY; - - udc_disable(dev); - - free_irq(dev->irq, dev); - iounmap(dev->base); - release_mem_region(dev->mem->start, resource_size(dev->mem)); - clk_put(dev->clk); - - platform_set_drvdata(pdev, NULL); - device_unregister(&dev->gadget.dev); - the_controller = NULL; - - return 0; -} - -#ifdef CONFIG_PM - -static int jz4740_udc_suspend(struct device *dev) -{ - struct jz4740_udc *udc = dev_get_drvdata(dev); - - if (udc->state == UDC_STATE_ENABLE) - udc_disable(udc); - - return 0; -} - -static int jz4740_udc_resume(struct device *dev) -{ - struct jz4740_udc *udc = dev_get_drvdata(dev); - - if (udc->state == UDC_STATE_ENABLE) - udc_enable(udc); - - return 0; -} - -static struct dev_pm_ops jz4740_udc_pm_ops = { - .suspend = jz4740_udc_suspend, - .resume = jz4740_udc_resume, -}; - -#define JZ4740_UDC_PM_OPS (&jz4740_udc_pm_ops) - -#else - -#define JZ4740_UDC_PM_OPS NULL - -#endif - -static struct platform_driver udc_driver = { - .probe = jz4740_udc_probe, - .remove = jz4740_udc_remove, - .driver = { - .name = "jz-udc", - .owner = THIS_MODULE, - .pm = JZ4740_UDC_PM_OPS, - }, -}; - -/*-------------------------------------------------------------------------*/ - -static int __init udc_init (void) -{ - return platform_driver_register(&udc_driver); -} -module_init(udc_init); - -static void __exit udc_exit (void) -{ - platform_driver_unregister(&udc_driver); -} -module_exit(udc_exit); - -MODULE_DESCRIPTION("JZ4740 USB Device Controller"); -MODULE_AUTHOR("Wei Jianli <jlwei@ingenic.cn>"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.h b/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.h deleted file mode 100644 index ac1540f05f..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/usb/gadget/jz4740_udc.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * linux/drivers/usb/gadget/jz4740_udc.h - * - * Ingenic JZ4740 on-chip high speed USB device controller - * - * Copyright (C) 2006 Ingenic Semiconductor Inc. - * Author: <jlwei@ingenic.cn> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __USB_GADGET_JZ4740_H__ -#define __USB_GADGET_JZ4740_H__ - -/*-------------------------------------------------------------------------*/ - -// Max packet size -#define EP0_MAXPACKETSIZE 64 -#define EPBULK_MAXPACKETSIZE 512 -#define EPINTR_MAXPACKETSIZE 64 - -#define UDC_MAX_ENDPOINTS 4 - -/*-------------------------------------------------------------------------*/ - -typedef enum ep_type { - ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt -} ep_type_t; - -struct jz4740_ep { - struct usb_ep ep; - struct jz4740_udc *dev; - - const struct usb_endpoint_descriptor *desc; - unsigned long pio_irqs; - - uint8_t stopped; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - - ep_type_t type; - size_t fifo; - u32 csr; - - uint32_t reg_addr; - struct list_head queue; -}; - -struct jz4740_request { - struct usb_request req; - struct list_head queue; -}; - -enum ep0state { - WAIT_FOR_SETUP, /* between STATUS ack and SETUP report */ - DATA_STATE_XMIT, /* data tx stage */ - DATA_STATE_NEED_ZLP, /* data tx zlp stage */ - WAIT_FOR_OUT_STATUS, /* status stages */ - DATA_STATE_RECV, /* data rx stage */ -}; - -/* For function binding with UDC Disable - Added by River */ -typedef enum { - UDC_STATE_ENABLE = 0, - UDC_STATE_DISABLE, -}udc_state_t; - -struct jz4740_udc { - struct usb_gadget gadget; - struct usb_gadget_driver *driver; - struct device *dev; - spinlock_t lock; - - enum ep0state ep0state; - struct jz4740_ep ep[UDC_MAX_ENDPOINTS]; - - unsigned char usb_address; - - udc_state_t state; - - struct resource *mem; - void __iomem *base; - int irq; - uint32_t in_mask; - uint32_t out_mask; - - struct clk *clk; -}; - -extern struct jz4740_udc *the_controller; - -#define ep_is_in(EP) (((EP)->bEndpointAddress&USB_DIR_IN)==USB_DIR_IN) -#define ep_maxpacket(EP) ((EP)->ep.maxpacket) -#define ep_index(EP) ((EP)->bEndpointAddress&0xF) - -#endif /* __USB_GADGET_JZ4740_H__ */ diff --git a/target/linux/xburst/files-2.6.32/drivers/video/backlight/gpm940b0.c b/target/linux/xburst/files-2.6.32/drivers/video/backlight/gpm940b0.c deleted file mode 100644 index 5cfb12f0e8..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/video/backlight/gpm940b0.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4720/JZ4740 SoC LCD framebuffer driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/module.h> -#include <linux/spi/spi.h> -#include <linux/lcd.h> -#include <linux/backlight.h> -#include <linux/delay.h> - -struct gpm940b0 { - struct spi_device *spi; - struct lcd_device *lcd; - struct backlight_device *bl; - unsigned enabled:1; -}; - -static int gpm940b0_write_reg(struct spi_device *spi, uint8_t reg, - uint8_t data) -{ - uint8_t buf[2]; - buf[0] = ((reg & 0x40) << 1) | (reg & 0x3f); - buf[1] = data; - - return spi_write(spi, buf, sizeof(buf)); -} - -static void gpm940b0_power_disable(struct gpm940b0 *gpm940b0) -{ - int ret = gpm940b0_write_reg(gpm940b0->spi, 0x5, 0xc6) ; - if (ret < 0) - printk("Failed to disable power: %d\n", ret); -} - -static void gpm940b0_power_enable(struct gpm940b0 *gpm940b0) -{ - gpm940b0_write_reg(gpm940b0->spi, 0x5, 0xc7); -} - - -static int gpm940b0_set_power(struct lcd_device *lcd, int power) -{ - struct gpm940b0 *gpm940b0 = lcd_get_data(lcd); - - switch (power) { - case FB_BLANK_UNBLANK: - mdelay(20); - gpm940b0->enabled = 1; - gpm940b0_power_enable(gpm940b0); - break; - default: - gpm940b0->enabled = 0; - gpm940b0_power_disable(gpm940b0); - mdelay(20); - break; - } - return 0; -} - -static int gpm940b0_set_contrast(struct lcd_device *lcd, int contrast) -{ - struct gpm940b0 *gpm940b0 = lcd_get_data(lcd); - gpm940b0_write_reg(gpm940b0->spi, 0x0d, contrast); - return 0; -} - -static int gpm940b0_set_mode(struct lcd_device *lcd, struct fb_videomode *mode) -{ - if (mode->xres != 320 && mode->yres != 240) - return -EINVAL; - - return 0; -} - -/* -int gpm940b0_bl_update_status(struct backlight_device *bl) -{ - struct gpm940b0 *gpm940b0 = bl_get_data(bl); - - gpm940b0->reg5 &= ~0x38; - gpm940b0->reg5 |= ((bl->props.brightness << 3) & 0x38); - - gpm940b0_write_reg(gpm940b0->spi, 0x5, gpm940b0->reg5); - - return 0; -}*/ - -static ssize_t reg_write(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - char *buf2; - uint32_t reg = simple_strtoul(buf, &buf2, 10); - uint32_t val = simple_strtoul(buf2 + 1, NULL, 10); - struct gpm940b0 *gpm940b0 = dev_get_drvdata(dev); - - if (reg < 0 || val < 0) - return -EINVAL; - - gpm940b0_write_reg(gpm940b0->spi, reg, val); - return count; -} - -static DEVICE_ATTR(reg, 0644, NULL, reg_write); - -static struct lcd_ops gpm940b0_lcd_ops = { - .set_power = gpm940b0_set_power, - .set_contrast = gpm940b0_set_contrast, - .set_mode = gpm940b0_set_mode, -}; - -#if 0 -static struct backlight_ops gpm940b0_bl_ops = { -/* .get_brightness = gpm940b0_bl_get_brightness,*/ - .update_status = gpm940b0_bl_update_status, -}; -#endif - -static int __devinit gpm940b0_probe(struct spi_device *spi) -{ - int ret; - struct gpm940b0 *gpm940b0; - - gpm940b0 = kmalloc(sizeof(*gpm940b0), GFP_KERNEL); - - spi->bits_per_word = 8; - - ret = spi_setup(spi); - if (ret) { - dev_err(&spi->dev, "Failed to setup spi\n"); - goto err_free_gpm940b0; - } - - gpm940b0->spi = spi; - - gpm940b0->lcd = lcd_device_register("gpm940b0-lcd", &spi->dev, gpm940b0, - &gpm940b0_lcd_ops); - - if (IS_ERR(gpm940b0->lcd)) { - ret = PTR_ERR(gpm940b0->lcd); - dev_err(&spi->dev, "Failed to register lcd device: %d\n", ret); - goto err_free_gpm940b0; - } - - gpm940b0->lcd->props.max_contrast = 255; - -#if 0 - gpm940b0->bl = backlight_device_register("gpm940b0-bl", &spi->dev, gpm940b0, - &gpm940b0_bl_ops); - - if (IS_ERR(gpm940b0->bl)) { - ret = PTR_ERR(gpm940b0->bl); - dev_err(&spi->dev, "Failed to register backlight device: %d\n", ret); - gpm940b0->bl = NULL; - } else { - gpm940b0->bl->props.max_brightness = 8; - gpm940b0->bl->props.brightness = 0; - gpm940b0->bl->props.power = FB_BLANK_UNBLANK; - } -#endif - - ret = device_create_file(&spi->dev, &dev_attr_reg); - if (ret) - goto err_unregister_lcd; - - gpm940b0->enabled = 1; - dev_set_drvdata(&spi->dev, gpm940b0); - - gpm940b0_write_reg(spi, 0x13, 0x01); - gpm940b0_write_reg(spi, 0x5, 0xc7); - return 0; -err_unregister_lcd: - lcd_device_unregister(gpm940b0->lcd); -err_free_gpm940b0: - kfree(gpm940b0); - return ret; -} - -static int __devexit gpm940b0_remove(struct spi_device *spi) -{ - struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); -#if 0 - if (gpm940b0->bl) - backlight_device_unregister(gpm940b0->bl); -#endif - - lcd_device_unregister(gpm940b0->lcd); - - spi_set_drvdata(spi, NULL); - kfree(gpm940b0); - return 0; -} - -#ifdef CONFIG_PM - -static int gpm940b0_suspend(struct spi_device *spi, pm_message_t state) -{ - struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); - if (gpm940b0->enabled) { - gpm940b0_power_disable(gpm940b0); - mdelay(10); - } - return 0; -} - -static int gpm940b0_resume(struct spi_device *spi) -{ - struct gpm940b0 *gpm940b0 = spi_get_drvdata(spi); - if (gpm940b0->enabled) - gpm940b0_power_enable(gpm940b0); - return 0; -} - -#else -#define gpm940b0_suspend NULL -#define gpm940b0_resume NULL -#endif - -static struct spi_driver gpm940b0_driver = { - .driver = { - .name = "gpm940b0", - .owner = THIS_MODULE, - }, - .probe = gpm940b0_probe, - .remove = __devexit_p(gpm940b0_remove), - .suspend = gpm940b0_suspend, - .resume = gpm940b0_resume, -}; - -static int __init gpm940b0_init(void) -{ - return spi_register_driver(&gpm940b0_driver); -} -module_init(gpm940b0_init); - -static void __exit gpm940b0_exit(void) -{ - return spi_unregister_driver(&gpm940b0_driver); -} -module_exit(gpm940b0_exit) - -MODULE_AUTHOR("Lars-Peter Clausen"); -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("LCD and backlight controll for Giantplus GPM940B0"); -MODULE_ALIAS("spi:gpm940b0"); diff --git a/target/linux/xburst/files-2.6.32/drivers/video/jz4740_fb.c b/target/linux/xburst/files-2.6.32/drivers/video/jz4740_fb.c deleted file mode 100644 index eeb702a6f3..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/video/jz4740_fb.c +++ /dev/null @@ -1,790 +0,0 @@ -/* - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> - * JZ4720/JZ4740 SoC LCD framebuffer driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/types.h> -#include <linux/platform_device.h> -#include <linux/console.h> -#include <linux/fb.h> -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <linux/mutex.h> -#include <linux/delay.h> -#include <linux/clk.h> - -#include <linux/jz4740_fb.h> -#include <asm/mach-jz4740/gpio.h> - -#define JZ_REG_LCD_CFG 0x00 -#define JZ_REG_LCD_VSYNC 0x04 -#define JZ_REG_LCD_HSYNC 0x08 -#define JZ_REG_LCD_VAT 0x0C -#define JZ_REG_LCD_DAH 0x10 -#define JZ_REG_LCD_DAV 0x14 -#define JZ_REG_LCD_PS 0x18 -#define JZ_REG_LCD_CLS 0x1C -#define JZ_REG_LCD_SPL 0x20 -#define JZ_REG_LCD_REV 0x24 -#define JZ_REG_LCD_CTRL 0x30 -#define JZ_REG_LCD_STATE 0x34 -#define JZ_REG_LCD_IID 0x38 -#define JZ_REG_LCD_DA0 0x40 -#define JZ_REG_LCD_SA0 0x44 -#define JZ_REG_LCD_FID0 0x48 -#define JZ_REG_LCD_CMD0 0x4C -#define JZ_REG_LCD_DA1 0x50 -#define JZ_REG_LCD_SA1 0x54 -#define JZ_REG_LCD_FID1 0x58 -#define JZ_REG_LCD_CMD1 0x5C - -#define JZ_LCD_CFG_SLCD BIT(31) -#define JZ_LCD_CFG_PS_DISABLE BIT(23) -#define JZ_LCD_CFG_CLS_DISABLE BIT(22) -#define JZ_LCD_CFG_SPL_DISABLE BIT(21) -#define JZ_LCD_CFG_REV_DISABLE BIT(20) -#define JZ_LCD_CFG_HSYNCM BIT(19) -#define JZ_LCD_CFG_PCLKM BIT(18) -#define JZ_LCD_CFG_INV BIT(17) -#define JZ_LCD_CFG_SYNC_DIR BIT(16) -#define JZ_LCD_CFG_PS_POLARITY BIT(15) -#define JZ_LCD_CFG_CLS_POLARITY BIT(14) -#define JZ_LCD_CFG_SPL_POLARITY BIT(13) -#define JZ_LCD_CFG_REV_POLARITY BIT(12) -#define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11) -#define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10) -#define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9) -#define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8) -#define JZ_LCD_CFG_18_BIT BIT(7) -#define JZ_LCD_CFG_PDW BIT(5) | BIT(4) -#define JZ_LCD_CFG_MODE_MASK 0xf - -#define JZ_LCD_CTRL_BURST_4 (0x0 << 28) -#define JZ_LCD_CTRL_BURST_8 (0x1 << 28) -#define JZ_LCD_CTRL_BURST_16 (0x2 << 28) -#define JZ_LCD_CTRL_RGB555 BIT(27) -#define JZ_LCD_CTRL_OFUP BIT(26) -#define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24) -#define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24) -#define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24) -#define JZ_LCD_CTRL_PDD_MASK (0xff << 16) -#define JZ_LCD_CTRL_EOF_IRQ BIT(13) -#define JZ_LCD_CTRL_SOF_IRQ BIT(12) -#define JZ_LCD_CTRL_OFU_IRQ BIT(11) -#define JZ_LCD_CTRL_IFU0_IRQ BIT(10) -#define JZ_LCD_CTRL_IFU1_IRQ BIT(9) -#define JZ_LCD_CTRL_DD_IRQ BIT(8) -#define JZ_LCD_CTRL_QDD_IRQ BIT(7) -#define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6) -#define JZ_LCD_CTRL_LSB_FISRT BIT(5) -#define JZ_LCD_CTRL_DISABLE BIT(4) -#define JZ_LCD_CTRL_ENABLE BIT(3) -#define JZ_LCD_CTRL_BPP_1 0x0 -#define JZ_LCD_CTRL_BPP_2 0x1 -#define JZ_LCD_CTRL_BPP_4 0x2 -#define JZ_LCD_CTRL_BPP_8 0x3 -#define JZ_LCD_CTRL_BPP_15_16 0x4 -#define JZ_LCD_CTRL_BPP_18_24 0x5 - -#define JZ_LCD_CMD_SOF_IRQ BIT(15) -#define JZ_LCD_CMD_EOF_IRQ BIT(16) -#define JZ_LCD_CMD_ENABLE_PAL BIT(12) - -#define JZ_LCD_SYNC_MASK 0x3ff - -#define JZ_LCD_STATE_DISABLED BIT(0) - -struct jzfb_framedesc { - uint32_t next; - uint32_t addr; - uint32_t id; - uint32_t cmd; -} __attribute__((packed)); - -struct jzfb { - struct fb_info *fb; - struct platform_device *pdev; - void __iomem *base; - struct resource *mem; - struct jz4740_fb_platform_data *pdata; - - size_t vidmem_size; - void *vidmem; - dma_addr_t vidmem_phys; - struct jzfb_framedesc *framedesc; - dma_addr_t framedesc_phys; - - struct clk *ldclk; - struct clk *lpclk; - - unsigned is_enabled:1; - struct mutex lock; /* Protecting against running enable/disable in paralell */ - - uint32_t pseudo_palette[256]; -}; - -static struct fb_fix_screeninfo jzfb_fix __devinitdata = { - .id = "JZ4740 FB", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .xpanstep = 0, - .ypanstep = 0, - .ywrapstep = 0, - .accel = FB_ACCEL_NONE, -}; - -const static struct jz_gpio_bulk_request jz_lcd_ctrl_pins[] = { - JZ_GPIO_BULK_PIN(LCD_PCLK), - JZ_GPIO_BULK_PIN(LCD_HSYNC), - JZ_GPIO_BULK_PIN(LCD_VSYNC), - JZ_GPIO_BULK_PIN(LCD_DE), - JZ_GPIO_BULK_PIN(LCD_PS), - JZ_GPIO_BULK_PIN(LCD_REV), -}; - -const static struct jz_gpio_bulk_request jz_lcd_data_pins[] = { - JZ_GPIO_BULK_PIN(LCD_DATA0), - JZ_GPIO_BULK_PIN(LCD_DATA1), - JZ_GPIO_BULK_PIN(LCD_DATA2), - JZ_GPIO_BULK_PIN(LCD_DATA3), - JZ_GPIO_BULK_PIN(LCD_DATA4), - JZ_GPIO_BULK_PIN(LCD_DATA5), - JZ_GPIO_BULK_PIN(LCD_DATA6), - JZ_GPIO_BULK_PIN(LCD_DATA7), - JZ_GPIO_BULK_PIN(LCD_DATA8), - JZ_GPIO_BULK_PIN(LCD_DATA9), - JZ_GPIO_BULK_PIN(LCD_DATA10), - JZ_GPIO_BULK_PIN(LCD_DATA11), - JZ_GPIO_BULK_PIN(LCD_DATA12), - JZ_GPIO_BULK_PIN(LCD_DATA13), - JZ_GPIO_BULK_PIN(LCD_DATA14), - JZ_GPIO_BULK_PIN(LCD_DATA15), - JZ_GPIO_BULK_PIN(LCD_DATA16), - JZ_GPIO_BULK_PIN(LCD_DATA17), -}; - -static unsigned int jzfb_num_ctrl_pins(struct jzfb *jzfb) -{ - unsigned int num; - - switch (jzfb->pdata->lcd_type) { - case JZ_LCD_TYPE_GENERIC_16_BIT: - num = 4; - break; - case JZ_LCD_TYPE_GENERIC_18_BIT: - num = 4; - break; - case JZ_LCD_TYPE_8BIT_SERIAL: - num = 3; - break; - default: - num = 0; - break; - } - return num; -} - -static unsigned int jzfb_num_data_pins(struct jzfb *jzfb) -{ - unsigned int num; - - switch (jzfb->pdata->lcd_type) { - case JZ_LCD_TYPE_GENERIC_16_BIT: - num = 16; - break; - case JZ_LCD_TYPE_GENERIC_18_BIT: - num = 19; - break; - case JZ_LCD_TYPE_8BIT_SERIAL: - num = 8; - break; - default: - num = 0; - break; - } - return num; -} - -static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, - unsigned transp, struct fb_info *fb) -{ - if (regno >= fb->cmap.len) - return -EINVAL; - - ((uint32_t*)fb->pseudo_palette)[regno] = red << 16 | green << 8 | blue; - - return 0; -} - -static int jzfb_get_controller_bpp(struct jzfb *jzfb) -{ - switch(jzfb->pdata->bpp) { - case 18: - case 24: - return 32; - case 15: - return 16; - default: - return jzfb->pdata->bpp; - } -} - -static struct fb_videomode *jzfb_get_mode(struct jzfb* jzfb, struct fb_var_screeninfo *var) -{ - size_t i; - struct fb_videomode *mode = jzfb->pdata->modes; - - for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) { - if (mode->xres == var->xres && mode->yres == var->yres) - return mode; - } - - return NULL; -} - -static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb) -{ - struct jzfb* jzfb = fb->par; - struct fb_videomode *mode; - - if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) && - var->bits_per_pixel != jzfb->pdata->bpp) - return -EINVAL; - - mode = jzfb_get_mode(jzfb, var); - if (mode == NULL) - return -EINVAL; - - fb_videomode_to_var(var, mode); - - switch (jzfb->pdata->bpp) { - case 8: - break; - case 15: - var->red.offset = 10; - var->red.length = 5; - var->green.offset = 6; - var->green.length = 5; - var->blue.offset = 0; - var->blue.length = 5; - break; - case 16: - var->red.offset = 11; - var->red.length = 5; - var->green.offset = 6; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 5; - break; - case 18: - var->red.offset = 16; - var->red.length = 6; - var->green.offset = 8; - var->green.length = 6; - var->blue.offset = 0; - var->blue.length = 6; - var->bits_per_pixel = 32; - break; - case 32: - case 24: - var->transp.offset = 24; - var->transp.length = 8; - var->red.offset = 16; - var->red.length = 8; - var->green.offset = 8; - var->green.length = 8; - var->blue.offset = 0; - var->blue.length = 8; - var->bits_per_pixel = 32; - break; - default: - break; - } - - return 0; -} - -static int jzfb_set_par(struct fb_info *info) -{ - struct jzfb* jzfb = info->par; - struct fb_var_screeninfo *var = &info->var; - struct fb_videomode *mode; - uint16_t hds, vds; - uint16_t hde, vde; - uint16_t ht, vt; - uint32_t ctrl; - uint32_t cfg; - unsigned long rate; - - mode = jzfb_get_mode(jzfb, var); - if (mode == NULL) - return -EINVAL; - - info->mode = mode; - - hds = mode->hsync_len + mode->left_margin; - hde = hds + mode->xres; - ht = hde + mode->right_margin; - - vds = mode->vsync_len + mode->upper_margin; - vde = vds + mode->yres; - vt = vde + mode->lower_margin; - - ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16; - - switch (jzfb->pdata->bpp) { - case 1: - ctrl |= JZ_LCD_CTRL_BPP_1; - break; - case 2: - ctrl |= JZ_LCD_CTRL_BPP_2; - break; - case 4: - ctrl |= JZ_LCD_CTRL_BPP_4; - break; - case 8: - ctrl |= JZ_LCD_CTRL_BPP_8; - break; - case 15: - ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */ - case 16: - ctrl |= JZ_LCD_CTRL_BPP_15_16; - break; - case 18: - case 24: - case 32: - ctrl |= JZ_LCD_CTRL_BPP_18_24; - break; - default: - break; - } - - cfg = 0; - cfg |= JZ_LCD_CFG_PS_DISABLE; - cfg |= JZ_LCD_CFG_CLS_DISABLE; - cfg |= JZ_LCD_CFG_SPL_DISABLE; - cfg |= JZ_LCD_CFG_REV_DISABLE; - - if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) - cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW; - - if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) - cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW; - - if (jzfb->pdata->pixclk_falling_edge) - cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE; - - if (jzfb->pdata->date_enable_active_low) - cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW; - - if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT) - cfg |= JZ_LCD_CFG_18_BIT; - - cfg |= jzfb->pdata->lcd_type & 0xf; - - if (mode->pixclock) { - rate = PICOS2KHZ(mode->pixclock) * 1000; - mode->refresh = rate / vt / ht; - } else { - if (jzfb->pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL) - rate = mode->refresh * (vt + 2 * mode->xres) * ht; - else - rate = mode->refresh * vt * ht; - - mode->pixclock = KHZ2PICOS(rate / 1000); - } - - mutex_lock(&jzfb->lock); - if (!jzfb->is_enabled) - clk_enable(jzfb->ldclk); - else - ctrl |= JZ_LCD_CTRL_ENABLE; - - writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC); - writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC); - - writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT); - - writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH); - writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV); - - writel(cfg, jzfb->base + JZ_REG_LCD_CFG); - - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); - - if (!jzfb->is_enabled) - clk_disable(jzfb->ldclk); - mutex_unlock(&jzfb->lock); - - clk_set_rate(jzfb->lpclk, rate); - clk_set_rate(jzfb->ldclk, rate * 3); - - return 0; -} - -static void jzfb_enable(struct jzfb *jzfb) -{ - uint32_t ctrl; - - clk_enable(jzfb->ldclk); - - jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); - jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); - - writel(0, jzfb->base + JZ_REG_LCD_STATE); - - writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); - - ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); - ctrl |= JZ_LCD_CTRL_ENABLE; - ctrl &= ~JZ_LCD_CTRL_DISABLE; - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); -} - -static void jzfb_disable(struct jzfb *jzfb) -{ - uint32_t ctrl; - - ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); - ctrl |= JZ_LCD_CTRL_DISABLE; - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); - do { - ctrl = readl(jzfb->base + JZ_REG_LCD_STATE); - } while (!(ctrl & JZ_LCD_STATE_DISABLED)); - - jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); - jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); - - clk_disable(jzfb->ldclk); -} - -static int jzfb_blank(int blank_mode, struct fb_info *info) -{ - struct jzfb* jzfb = info->par; - - switch (blank_mode) { - case FB_BLANK_UNBLANK: - mutex_lock(&jzfb->lock); - if (jzfb->is_enabled) { - mutex_unlock(&jzfb->lock); - return 0; - } - - jzfb_enable(jzfb); - jzfb->is_enabled = 1; - - mutex_unlock(&jzfb->lock); - - break; - default: - mutex_lock(&jzfb->lock); - if (!jzfb->is_enabled) { - mutex_unlock(&jzfb->lock); - return 0; - } - - jzfb_disable(jzfb); - - jzfb->is_enabled = 0; - mutex_unlock(&jzfb->lock); - break; - } - - return 0; -} - -static int jzfb_alloc_devmem(struct jzfb *jzfb) -{ - int max_videosize = 0; - struct fb_videomode *mode = jzfb->pdata->modes; - void *page; - int i; - - for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) { - if (max_videosize < mode->xres * mode->yres) - max_videosize = mode->xres * mode->yres; - } - - max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3; - - jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev, - sizeof(*jzfb->framedesc), - &jzfb->framedesc_phys, GFP_KERNEL); - - if (!jzfb->framedesc) - return -ENOMEM; - - jzfb->vidmem_size = PAGE_ALIGN(max_videosize); - jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev, - jzfb->vidmem_size, - &jzfb->vidmem_phys, GFP_KERNEL); - - if (!jzfb->vidmem) { - goto err_free_framedesc; - } - - for (page = jzfb->vidmem; - page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size); - page += PAGE_SIZE) { - SetPageReserved(virt_to_page(page)); - } - - - jzfb->framedesc->next = jzfb->framedesc_phys; - jzfb->framedesc->addr = jzfb->vidmem_phys; - jzfb->framedesc->id = 0xdeafbead; - jzfb->framedesc->cmd = 0; - jzfb->framedesc->cmd |= max_videosize / 4; - - return 0; - -err_free_framedesc: - dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), - jzfb->framedesc, jzfb->framedesc_phys); - return -ENOMEM; -} - -static void jzfb_free_devmem(struct jzfb *jzfb) -{ - dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size, - jzfb->vidmem, jzfb->vidmem_phys); - dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), - jzfb->framedesc, jzfb->framedesc_phys); -} - -static struct fb_ops jzfb_ops = { - .owner = THIS_MODULE, - .fb_check_var = jzfb_check_var, - .fb_set_par = jzfb_set_par, - .fb_blank = jzfb_blank, - .fb_fillrect = sys_fillrect, - .fb_copyarea = sys_copyarea, - .fb_imageblit = sys_imageblit, - .fb_setcolreg = jzfb_setcolreg, -}; - -static int __devinit jzfb_probe(struct platform_device *pdev) -{ - int ret; - struct jzfb *jzfb; - struct fb_info *fb; - struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data; - struct resource *mem; - - if (!pdata) { - dev_err(&pdev->dev, "Missing platform data\n"); - return -ENOENT; - } - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!mem) { - dev_err(&pdev->dev, "Failed to get register memory resource\n"); - return -ENOENT; - } - - mem = request_mem_region(mem->start, resource_size(mem), pdev->name); - - if (!mem) { - dev_err(&pdev->dev, "Failed to request register memory region\n"); - return -EBUSY; - } - - - fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); - - if (!fb) { - dev_err(&pdev->dev, "Failed to allocate framebuffer device\n"); - ret = -ENOMEM; - goto err_release_mem_region; - } - - fb->fbops = &jzfb_ops; - fb->flags = FBINFO_DEFAULT; - - jzfb = fb->par; - jzfb->pdev = pdev; - jzfb->pdata = pdata; - jzfb->mem = mem; - - jzfb->ldclk = clk_get(&pdev->dev, "lcd"); - jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk"); - - if (IS_ERR(jzfb->ldclk)) { - ret = PTR_ERR(jzfb->ldclk); - dev_err(&pdev->dev, "Faild to get device clock: %d\n", ret); - goto err_framebuffer_release; - } - - if (IS_ERR(jzfb->lpclk)) { - ret = PTR_ERR(jzfb->ldclk); - dev_err(&pdev->dev, "Faild to get pixel clock: %d\n", ret); - goto err_framebuffer_release; - } - - - jzfb->base = ioremap(mem->start, resource_size(mem)); - - if (!jzfb->base) { - dev_err(&pdev->dev, "Failed to ioremap register memory region\n"); - ret = -EBUSY; - goto err_framebuffer_release; - } - - platform_set_drvdata(pdev, jzfb); - - fb_videomode_to_modelist(pdata->modes, pdata->num_modes, - &fb->modelist); - fb->mode = pdata->modes; - - fb_videomode_to_var(&fb->var, fb->mode); - fb->var.bits_per_pixel = pdata->bpp; - jzfb_check_var(&fb->var, fb); - - ret = jzfb_alloc_devmem(jzfb); - if (ret) { - dev_err(&pdev->dev, "Failed to allocate video memory\n"); - goto err_iounmap; - } - - fb->fix = jzfb_fix; - fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8; - fb->fix.mmio_start = mem->start; - fb->fix.mmio_len = resource_size(mem); - fb->fix.smem_start = jzfb->vidmem_phys; - fb->fix.smem_len = fb->fix.line_length * fb->var.yres; - fb->screen_base = jzfb->vidmem; - fb->pseudo_palette = jzfb->pseudo_palette; - - fb_alloc_cmap(&fb->cmap, 256, 0); - - mutex_init(&jzfb->lock); - - clk_enable(jzfb->ldclk); - jzfb->is_enabled = 1; - - writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); - jzfb_set_par(fb); - - jz_gpio_bulk_request(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); - jz_gpio_bulk_request(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); - - ret = register_framebuffer(fb); - if (ret) { - dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret); - goto err_free_devmem; - } - - jzfb->fb = fb; - - return 0; -err_free_devmem: - jzfb_free_devmem(jzfb); -err_iounmap: - iounmap(jzfb->base); -err_framebuffer_release: - framebuffer_release(fb); -err_release_mem_region: - release_mem_region(mem->start, resource_size(mem)); - return ret; -} - -static int __devexit jzfb_remove(struct platform_device *pdev) -{ - struct jzfb *jzfb = platform_get_drvdata(pdev); - - jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb)); - jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); - iounmap(jzfb->base); - release_mem_region(jzfb->mem->start, resource_size(jzfb->mem)); - jzfb_free_devmem(jzfb); - platform_set_drvdata(pdev, NULL); - framebuffer_release(jzfb->fb); - return 0; -} - -#ifdef CONFIG_PM - -static int jzfb_suspend(struct device *dev) -{ - struct jzfb *jzfb = dev_get_drvdata(dev); - - acquire_console_sem(); - fb_set_suspend(jzfb->fb, 1); - release_console_sem(); - - mutex_lock(&jzfb->lock); - if (jzfb->is_enabled) - jzfb_disable(jzfb); - mutex_unlock(&jzfb->lock); - - return 0; -} - -static int jzfb_resume(struct device *dev) -{ - struct jzfb *jzfb = dev_get_drvdata(dev); - clk_enable(jzfb->ldclk); - - mutex_lock(&jzfb->lock); - if (jzfb->is_enabled) - jzfb_enable(jzfb); - mutex_unlock(&jzfb->lock); - - acquire_console_sem(); - fb_set_suspend(jzfb->fb, 0); - release_console_sem(); - - return 0; -} - -static const struct dev_pm_ops jzfb_pm_ops = { - .suspend = jzfb_suspend, - .resume = jzfb_resume, - .poweroff = jzfb_suspend, - .restore = jzfb_resume, -}; - -#define JZFB_PM_OPS (&jzfb_pm_ops) - -#else -#define JZFB_PM_OPS NULL -#endif - -static struct platform_driver jzfb_driver = { - .probe = jzfb_probe, - .remove = __devexit_p(jzfb_remove), - - .driver = { - .name = "jz4740-fb", - .pm = JZFB_PM_OPS, - }, -}; - -int __init jzfb_init(void) -{ - return platform_driver_register(&jzfb_driver); -} -module_init(jzfb_init); - -void __exit jzfb_exit(void) -{ - platform_driver_unregister(&jzfb_driver); -} -module_exit(jzfb_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -MODULE_DESCRIPTION("JZ4720/JZ4740 SoC LCD framebuffer driver"); -MODULE_ALIAS("platform:jz4740-fb"); -MODULE_ALIAS("platform:jz4720-fb"); diff --git a/target/linux/xburst/files-2.6.32/drivers/video/metronomefb.c b/target/linux/xburst/files-2.6.32/drivers/video/metronomefb.c deleted file mode 100644 index 390d26e0d5..0000000000 --- a/target/linux/xburst/files-2.6.32/drivers/video/metronomefb.c +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * linux/drivers/video/metronomefb.c -- FB driver for Metronome controller - * - * Copyright (C) 2008, Jaya Kumar - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * - * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven. - * - * This work was made possible by help and equipment support from E-Ink - * Corporation. http://support.eink.com/community - * - * This driver is written to be used with the Metronome display controller. - * It is intended to be architecture independent. A board specific driver - * must be used to perform all the physical IO interactions. An example - * is provided as am200epd.c - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/list.h> -#include <linux/firmware.h> -#include <linux/dma-mapping.h> -#include <linux/uaccess.h> -#include <linux/irq.h> -#include <linux/ctype.h> - -#include <video/metronomefb.h> - -#include <asm/unaligned.h> - -#define WF_MODE_INIT 0 /* Initialization */ -#define WF_MODE_MU 1 /* Monochrome update */ -#define WF_MODE_GU 2 /* Grayscale update */ -#define WF_MODE_GC 3 /* Grayscale clearing */ - -static int temp = 25; - -/* frame differs from image. frame includes non-visible pixels */ -struct epd_frame { - int fw; /* frame width */ - int fh; /* frame height */ - u16 config[4]; - int wfm_size; -}; - -static const struct epd_frame epd_frame_table[] = { - { - .fw = 832, - .fh = 622, - .config = { - 15 /* sdlew */ - | 2 << 8 /* sdosz */ - | 0 << 11 /* sdor */ - | 0 << 12 /* sdces */ - | 0 << 15, /* sdcer */ - 42 /* gdspl */ - | 1 << 8 /* gdr1 */ - | 1 << 9 /* sdshr */ - | 0 << 15, /* gdspp */ - 18 /* gdspw */ - | 0 << 15, /* dispc */ - 599 /* vdlc */ - | 0 << 11 /* dsi */ - | 0 << 12, /* dsic */ - }, - .wfm_size = 47001, - }, - { - .fw = 1088, - .fh = 791, - .config = { - 0x0104, - 0x031f, - 0x0088, - 0x02ff, - }, - .wfm_size = 46770, - }, - { - .fw = 1200, - .fh = 842, - .config = { - 0x0101, - 0x030e, - 0x0012, - 0x0280, - }, - .wfm_size = 46770, - }, - { - .fw = 800, - .fh = 600, - .config = { - 15 /* sdlew */ - | 2 << 8 /* sdosz */ - | 0 << 11 /* sdor */ - | 0 << 12 /* sdces */ - | 0 << 15, /* sdcer */ - 42 /* gdspl */ - | 1 << 8 /* gdr1 */ - | 1 << 9 /* sdshr */ - | 0 << 15, /* gdspp */ - 18 /* gdspw */ - | 0 << 15, /* dispc */ - 599 /* vdlc */ - | 0 << 11 /* dsi */ - | 0 << 12, /* dsic */ - }, - .wfm_size = 46901, - }, -}; - -static const struct fb_fix_screeninfo metronomefb_fix __devinitconst = { - .id = "metronomefb", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_STATIC_PSEUDOCOLOR, - .xpanstep = 0, - .ypanstep = 0, - .ywrapstep = 0, - .accel = FB_ACCEL_NONE, -}; - -static const struct fb_var_screeninfo metronomefb_var __devinitconst = { - .bits_per_pixel = 8, - .grayscale = 1, - .nonstd = 1, - .red = { 4, 3, 0 }, - .green = { 0, 0, 0 }, - .blue = { 0, 0, 0 }, - .transp = { 0, 0, 0 }, -}; - -/* the waveform structure that is coming from userspace firmware */ -struct waveform_hdr { - u8 stuff[32]; - - u8 wmta[3]; - u8 fvsn; - - u8 luts; - u8 mc; - u8 trc; - u8 stuff3; - - u8 endb; - u8 swtb; - u8 stuff2a[2]; - - u8 stuff2b[3]; - u8 wfm_cs; -} __attribute__ ((packed)); - -/* main metronomefb functions */ -static u8 calc_cksum(int start, int end, u8 *mem) -{ - u8 tmp = 0; - int i; - - for (i = start; i < end; i++) - tmp += mem[i]; - - return tmp; -} - -static u16 calc_img_cksum(u16 *start, int length) -{ - u16 tmp = 0; - - while (length--) - tmp += *start++; - - return tmp; -} - -/* here we decode the incoming waveform file and populate metromem */ -static int load_waveform(u8 *mem, size_t size, int m, int t, - struct metronomefb_par *par) -{ - int tta; - int wmta; - int trn = 0; - int i; - unsigned char v; - u8 cksum; - int cksum_idx; - int wfm_idx, owfm_idx; - int mem_idx = 0; - struct waveform_hdr *wfm_hdr; - u8 *metromem = par->metromem_wfm; - struct device *dev = &par->pdev->dev; - u8 mc, trc; - u16 *p; - u16 img_cksum; - - dev_dbg(dev, "Loading waveforms, mode %d, temperature %d\n", m, t); - - wfm_hdr = (struct waveform_hdr *) mem; - - if (wfm_hdr->fvsn != 1) { - dev_err(dev, "Error: bad fvsn %x\n", wfm_hdr->fvsn); - return -EINVAL; - } - if (wfm_hdr->luts != 0) { - dev_err(dev, "Error: bad luts %x\n", wfm_hdr->luts); - return -EINVAL; - } - cksum = calc_cksum(32, 47, mem); - if (cksum != wfm_hdr->wfm_cs) { - dev_err(dev, "Error: bad cksum %x != %x\n", cksum, - wfm_hdr->wfm_cs); - return -EINVAL; - } - mc = wfm_hdr->mc + 1; - trc = wfm_hdr->trc + 1; - - for (i = 0; i < 5; i++) { - if (*(wfm_hdr->stuff2a + i) != 0) { - dev_err(dev, "Error: unexpected value in padding\n"); - return -EINVAL; - } - } - - /* calculating trn. trn is something used to index into - the waveform. presumably selecting the right one for the - desired temperature. it works out the offset of the first - v that exceeds the specified temperature */ - if ((sizeof(*wfm_hdr) + trc) > size) - return -EINVAL; - - for (i = sizeof(*wfm_hdr); i <= sizeof(*wfm_hdr) + trc; i++) { - if (mem[i] > t) { - trn = i - sizeof(*wfm_hdr) - 1; - break; - } - } - - /* check temperature range table checksum */ - cksum_idx = sizeof(*wfm_hdr) + trc + 1; - if (cksum_idx > size) - return -EINVAL; - cksum = calc_cksum(sizeof(*wfm_hdr), cksum_idx, mem); - if (cksum != mem[cksum_idx]) { - dev_err(dev, "Error: bad temperature range table cksum" - " %x != %x\n", cksum, mem[cksum_idx]); - return -EINVAL; - } - - /* check waveform mode table address checksum */ - wmta = get_unaligned_le32(wfm_hdr->wmta) & 0x00FFFFFF; - cksum_idx = wmta + m*4 + 3; - if (cksum_idx > size) - return -EINVAL; - cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); - if (cksum != mem[cksum_idx]) { - dev_err(dev, "Error: bad mode table address cksum" - " %x != %x\n", cksum, mem[cksum_idx]); - return -EINVAL; - } - - /* check waveform temperature table address checksum */ - tta = get_unaligned_le32(mem + wmta + m * 4) & 0x00FFFFFF; - cksum_idx = tta + trn*4 + 3; - if (cksum_idx > size) - return -EINVAL; - cksum = calc_cksum(cksum_idx - 3, cksum_idx, mem); - if (cksum != mem[cksum_idx]) { - dev_err(dev, "Error: bad temperature table address cksum" - " %x != %x\n", cksum, mem[cksum_idx]); - return -EINVAL; - } - - /* here we do the real work of putting the waveform into the - metromem buffer. this does runlength decoding of the waveform */ - wfm_idx = get_unaligned_le32(mem + tta + trn * 4) & 0x00FFFFFF; - owfm_idx = wfm_idx; - if (wfm_idx > size) - return -EINVAL; - while (wfm_idx < size) { - unsigned char rl; - v = mem[wfm_idx++]; - if (v == wfm_hdr->swtb) { - while (((v = mem[wfm_idx++]) != wfm_hdr->swtb) && - wfm_idx < size) - metromem[mem_idx++] = v; - - continue; - } - - if (v == wfm_hdr->endb) - break; - - rl = mem[wfm_idx++]; - for (i = 0; i <= rl; i++) - metromem[mem_idx++] = v; - } - - cksum_idx = wfm_idx; - if (cksum_idx > size) - return -EINVAL; - dev_dbg(dev, "mem_idx = %u\n", mem_idx); - cksum = calc_cksum(owfm_idx, cksum_idx, mem); - if (cksum != mem[cksum_idx]) { - dev_err(dev, "Error: bad waveform data cksum" - " %x != %x\n", cksum, mem[cksum_idx]); - return -EINVAL; - } - par->frame_count = (mem_idx/64); - - p = (u16 *)par->metromem_wfm; - img_cksum = calc_img_cksum(p, 16384 / 2); - p[16384 / 2] = __cpu_to_le16(img_cksum); - - par->current_wf_mode = m; - par->current_wf_temp = t; - - return 0; -} - -static int check_err(struct metronomefb_par *par) -{ - int res; - - res = par->board->get_err(par); - dev_dbg(&par->pdev->dev, "ERR = %d\n", res); - return res; -} - -static inline int wait_for_rdy(struct metronomefb_par *par) -{ - int res = 0; - - if (!par->board->get_rdy(par)) - res = par->board->met_wait_event_intr(par); - - return res; -} - -static int metronome_display_cmd(struct metronomefb_par *par) -{ - int i; - u16 cs; - u16 opcode; - int res; - - res = wait_for_rdy(par); - if (res) - return res; - - dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__); - /* setup display command - we can't immediately set the opcode since the controller - will try parse the command before we've set it all up - so we just set cs here and set the opcode at the end */ - - if (par->metromem_cmd->opcode == 0xCC40) - opcode = cs = 0xCC41; - else - opcode = cs = 0xCC40; - - /* set the args ( 2 bytes ) for display */ - i = 0; - par->metromem_cmd->args[i] = 0 << 3 /* border update */ - | (3 << 4) -// | ((borderval++ % 4) & 0x0F) << 4 - | (par->frame_count - 1) << 8; - cs += par->metromem_cmd->args[i++]; - - /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); - - par->metromem_cmd->csum = cs; - par->metromem_cmd->opcode = opcode; /* display cmd */ - - return 0; - -} - -static int __devinit metronome_powerup_cmd(struct metronomefb_par *par) -{ - int i; - u16 cs; - int res; - - dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__); - /* setup power up command */ - par->metromem_cmd->opcode = 0x1234; /* pwr up pseudo cmd */ - cs = par->metromem_cmd->opcode; - - /* set pwr1,2,3 to 1024 */ - for (i = 0; i < 3; i++) { -// par->metromem_cmd->args[i] = 1024; - par->metromem_cmd->args[i] = 100; - cs += par->metromem_cmd->args[i]; - } - - /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); - - par->metromem_cmd->csum = cs; - - msleep(1); - par->board->set_rst(par, 1); - - msleep(1); - par->board->set_stdby(par, 1); - - res = par->board->met_wait_event(par); - dev_dbg(&par->pdev->dev, "%s: EXIT: %d\n", __func__, res); - return res; -} - -static int __devinit metronome_config_cmd(struct metronomefb_par *par) -{ - /* setup config command - we can't immediately set the opcode since the controller - will try parse the command before we've set it all up */ - - dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__); - memcpy(par->metromem_cmd->args, par->epd_frame->config, - sizeof(par->epd_frame->config)); - /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + 4), 0, (32-4)*2); - - par->metromem_cmd->csum = 0xCC10; - par->metromem_cmd->csum += calc_img_cksum(par->metromem_cmd->args, 4); - par->metromem_cmd->opcode = 0xCC10; /* config cmd */ - - return par->board->met_wait_event(par); -} - -static int __devinit metronome_init_cmd(struct metronomefb_par *par) -{ - int i; - u16 cs; - - /* setup init command - we can't immediately set the opcode since the controller - will try parse the command before we've set it all up - so we just set cs here and set the opcode at the end */ - - dev_dbg(&par->pdev->dev, "%s: ENTER\n", __func__); - cs = 0xCC20; - - /* set the args ( 2 bytes ) for init */ - i = 0; - par->metromem_cmd->args[i] = 0x0007; - cs += par->metromem_cmd->args[i++]; - - /* the rest are 0 */ - memset((u8 *) (par->metromem_cmd->args + i), 0, (32-i)*2); - - par->metromem_cmd->csum = cs; - par->metromem_cmd->opcode = 0xCC20; /* init cmd */ - - return par->board->met_wait_event(par); -} - -static int metronome_bootup(struct metronomefb_par *par) -{ - int res; - - res = metronome_powerup_cmd(par); - if (res) { - dev_err(&par->pdev->dev, "metronomefb: POWERUP cmd failed\n"); - goto finish; - } - - check_err(par); - res = metronome_config_cmd(par); - if (res) { - dev_err(&par->pdev->dev, "metronomefb: CONFIG cmd failed\n"); - goto finish; - } - check_err(par); - - res = metronome_init_cmd(par); - if (res) - dev_err(&par->pdev->dev, "metronomefb: INIT cmd failed\n"); - check_err(par); - -finish: - return res; -} - -static int __devinit metronome_init_regs(struct metronomefb_par *par) -{ - int res; - - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_ON); - - res = metronome_bootup(par); - - return res; -} - -static uint16_t metronomefb_update_img_buffer_rotated(struct metronomefb_par *par) -{ - int x, y; - int xstep, ystep; - int i, j; - uint16_t cksum = 0; - uint8_t *buf = par->info->screen_base; - uint32_t *img = (uint32_t *)(par->metromem_img); - int fw = par->epd_frame->fw; - int fh = par->epd_frame->fh; - int fw_buf = fw / 4; - uint32_t *fxbuckets = par->fxbuckets; - uint32_t *fybuckets = par->fybuckets; - uint32_t diff; - uint32_t tmp; - - switch (par->info->var.rotate) { - case FB_ROTATE_CW: - xstep = -fh; - ystep = fw * fh + 1; - j = (fw - 1) * fh; - break; - case FB_ROTATE_UD: - xstep = -1; - ystep = 0; - j = fw * fh - 1; - break; - case FB_ROTATE_CCW: - xstep = fh; - ystep = -fw * fh - 1; - j = fh - 1; - break; - default: - BUG(); - break; - } - - memset(fxbuckets, 0, fw_buf * sizeof(*fxbuckets)); - memset(fybuckets, 0, fh * sizeof(*fybuckets)); - - i = 0; - for (y = 0; y < fh; y++) { - for(x = 0; x < fw_buf; x++, i++) { - if (j < 0 || j >= fw * fh) { - printk("moo: %d %d %d %d %d\n", j, x, y, fw_buf, fh); - return 0; - } - tmp = (buf[j] << 5); - j += xstep; - tmp |= (buf[j] << 13); - j += xstep; - tmp |= (buf[j] << 21); - j += xstep; - tmp |= (buf[j] << 29); - j += xstep; - tmp &= 0xe0e0e0e0; - - img[i] &= 0xf0f0f0f0; - diff = img[i] ^ tmp; - - fxbuckets[x] |= diff; - fybuckets[y] |= diff; - - img[i] = (img[i] >> 4) | tmp; - cksum += img[i] & 0x0000ffff; - cksum += (img[i] >> 16); - - } - j += ystep; - } - - return cksum; -} - -static uint16_t metronomefb_update_img_buffer_normal(struct metronomefb_par *par) -{ - int x, y, i; - uint16_t cksum = 0; - uint32_t *buf = (uint32_t __force *)par->info->screen_base; - uint32_t *img = (uint32_t *)(par->metromem_img); - uint32_t diff; - uint32_t tmp; - int fw = par->epd_frame->fw; - int fh = par->epd_frame->fh; - int fw_buf = fw / sizeof(*buf); - uint32_t *fxbuckets = par->fxbuckets; - uint32_t *fybuckets = par->fybuckets; - - memset(fxbuckets, 0, fw_buf * sizeof(*fxbuckets)); - memset(fybuckets, 0, fh * sizeof(*fybuckets)); - - i = 0; - for (y = 0; y < fh; y++) { - for(x = 0; x < fw_buf; x++, i++) { - tmp = (buf[i] << 5) & 0xe0e0e0e0; - img[i] &= 0xf0f0f0f0; - diff = img[i] ^ tmp; - - fxbuckets[x] |= diff; - fybuckets[y] |= diff; - - img[i] = (img[i] >> 4) | tmp; - cksum += img[i] & 0x0000ffff; - cksum += (img[i] >> 16); - } - } - - return cksum; -} - -static unsigned int metronomefb_get_change_count(struct metronomefb_par *par) -{ - int min_x; - int max_x; - int min_y; - int max_y; - int fw = par->epd_frame->fw / 4; - int fh = par->epd_frame->fh; - unsigned int change_count; - uint32_t *fxbuckets = par->fxbuckets; - uint32_t *fybuckets = par->fybuckets; - - for (min_x = 0; min_x < fw; ++min_x) { - if(fxbuckets[min_x]) - break; - } - - for (max_x = fw - 1; max_x >= 0; --max_x) { - if(fxbuckets[max_x]) - break; - } - - for (min_y = 0; min_y < fh; min_y++) { - if(fybuckets[min_y]) - break; - } - - for (max_y = fh - 1; max_y >= 0; --max_y) { - if(fybuckets[max_y]) - break; - } - - if ((min_x > max_x) || (min_y > max_y)) - change_count = 0; - else - change_count = (max_x - min_x + 1) * (max_y - min_y + 1) * 4; - - dev_dbg(&par->pdev->dev, "min_x = %d, max_x = %d, min_y = %d, max_y = %d\n", - min_x, max_x, min_y, max_y); - - return change_count; -} - -static void metronomefb_dpy_update(struct metronomefb_par *par, int clear_all) -{ - unsigned int fbsize = par->info->fix.smem_len; - uint16_t cksum; - int m; - - wait_for_rdy(par); - - if (par->info->var.rotate == 0) - cksum = metronomefb_update_img_buffer_normal(par); - else - cksum = metronomefb_update_img_buffer_rotated(par); - - *par->metromem_img_csum = __cpu_to_le16(cksum); - - if (clear_all || par->is_first_update || - (par->partial_updates_count == par->partial_autorefresh_interval)) { - m = WF_MODE_GC; - par->partial_updates_count = 0; - } else { - int change_count = metronomefb_get_change_count(par); - if (change_count < fbsize / 100 * par->manual_refresh_threshold) - m = WF_MODE_GU; - else - m = WF_MODE_GC; - - dev_dbg(&par->pdev->dev, "change_count = %u, treshold = %u%% (%u pixels)\n", - change_count, par->manual_refresh_threshold, - fbsize / 100 * par->manual_refresh_threshold); - ++par->partial_updates_count; - } - - if (m != par->current_wf_mode) - load_waveform((u8 *) par->firmware->data, par->firmware->size, - m, par->current_wf_temp, par); - -again: - metronome_display_cmd(par); - wait_for_rdy(par); - if (unlikely(check_err(par))) { - par->board->set_stdby(par, 0); - printk("Resetting Metronome\n"); - par->board->set_rst(par, 0); - mdelay(1); - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_OFF); - - mdelay(1); - load_waveform((u8 *) par->firmware->data, par->firmware->size, - WF_MODE_GC, par->current_wf_temp, par); - - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_ON); - metronome_bootup(par); - - goto again; - } - - par->is_first_update = 0; -} - -/* this is called back from the deferred io workqueue */ -static void metronomefb_dpy_deferred_io(struct fb_info *info, - struct list_head *pagelist) -{ - struct metronomefb_par *par = info->par; - - /* We will update entire display because we need to change - * 'previous image' field in pixels which was changed at - * previous refresh - */ - mutex_lock(&par->lock); - metronomefb_dpy_update(par, 0); - mutex_unlock(&par->lock); -} - -static void metronomefb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct metronomefb_par *par = info->par; - - mutex_lock(&par->lock); - sys_fillrect(info, rect); - metronomefb_dpy_update(par, 0); - mutex_unlock(&par->lock); -} - -static void metronomefb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct metronomefb_par *par = info->par; - - mutex_lock(&par->lock); - sys_copyarea(info, area); - metronomefb_dpy_update(par, 0); - mutex_unlock(&par->lock); -} - -static void metronomefb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct metronomefb_par *par = info->par; - - mutex_lock(&par->lock); - sys_imageblit(info, image); - metronomefb_dpy_update(par, 0); - mutex_unlock(&par->lock); -} - -/* - * this is the slow path from userspace. they can seek and write to - * the fb. it is based on fb_sys_write - */ -static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct metronomefb_par *par = info->par; - unsigned long p = *ppos; - void *dst; - int err = 0; - unsigned long total_size; - - if (info->state != FBINFO_STATE_RUNNING) - return -EPERM; - - total_size = info->fix.smem_len; - - if (p > total_size) - return -EFBIG; - - if (count > total_size) { - err = -EFBIG; - count = total_size; - } - - if (count + p > total_size) { - if (!err) - err = -ENOSPC; - - count = total_size - p; - } - - dst = (void __force *)(info->screen_base + p); - - mutex_lock(&par->lock); - - if (copy_from_user(dst, buf, count)) - err = -EFAULT; - - if (!err) - *ppos += count; - - metronomefb_dpy_update(par, 0); - mutex_unlock(&par->lock); - - return (err) ? err : count; -} - -static int metronome_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct metronomefb_par *par = info->par; - - if (par->epd_frame->fw == var->xres && par->epd_frame->fh == var->yres) - return 0; - - return -EINVAL; -} - -static int metronomefb_set_par(struct fb_info *info) -{ - struct metronomefb_par *par = info->par; - - switch (info->var.rotate) { - case FB_ROTATE_CW: - case FB_ROTATE_CCW: - info->fix.line_length = info->var.yres; - break; - case FB_ROTATE_UD: - default: - info->fix.line_length = info->var.xres; - break; - } - - mutex_lock(&par->lock); - metronomefb_dpy_update(info->par, 1); - mutex_unlock(&par->lock); - - return 0; -} - -static struct fb_ops metronomefb_ops = { - .owner = THIS_MODULE, - .fb_write = metronomefb_write, - .fb_fillrect = metronomefb_fillrect, - .fb_copyarea = metronomefb_copyarea, - .fb_imageblit = metronomefb_imageblit, - .fb_check_var = metronome_check_var, - .fb_set_par = metronomefb_set_par, -}; - -static struct fb_deferred_io metronomefb_defio = { - .delay = HZ / 4, - .deferred_io = metronomefb_dpy_deferred_io, -}; - -static ssize_t metronomefb_defio_delay_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - - sprintf(buf, "%lu\n", info->fbdefio->delay * 1000 / HZ); - return strlen(buf) + 1; -} - -static ssize_t metronomefb_defio_delay_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct fb_info *info = dev_get_drvdata(dev); - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - ssize_t ret = -EINVAL; - - if (*after && isspace(*after)) - count++; - - state = state * HZ / 1000; - - if (!state) - state = 1; - - if (count == size) { - ret = count; - info->fbdefio->delay = state; - } - - return ret; -} - -static ssize_t metronomefb_manual_refresh_thr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - - return sprintf(buf, "%u\n", par->manual_refresh_threshold); -} - -static ssize_t metronomefb_manual_refresh_thr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - char *after; - unsigned long val = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - ssize_t ret = -EINVAL; - - if (*after && isspace(*after)) - count++; - - if (val > 100) - return -EINVAL; - - - if (count == size) { - ret = count; - par->manual_refresh_threshold = val; - } - - return ret; -} - -static ssize_t metronomefb_autorefresh_interval_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - - return sprintf(buf, "%u\n", par->partial_autorefresh_interval); -} - -static ssize_t metronomefb_autorefresh_interval_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - char *after; - unsigned long val = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - ssize_t ret = -EINVAL; - - if (*after && isspace(*after)) - count++; - - if (val > 100) - return -EINVAL; - - - if (count == size) { - ret = count; - par->partial_autorefresh_interval = val; - } - - return ret; -} - -static ssize_t metronomefb_temp_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - - return sprintf(buf, "%u\n", par->current_wf_temp); -} - -static ssize_t metronomefb_temp_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t size) -{ - struct fb_info *info = dev_get_drvdata(dev); - struct metronomefb_par *par = info->par; - char *after; - unsigned long val = simple_strtoul(buf, &after, 10); - size_t count = after - buf; - ssize_t ret = -EINVAL; - - if (*after && isspace(*after)) - count++; - - if (val > 100) - return -EINVAL; - - - if (count == size) { - ret = count; - if (val != par->current_wf_temp) - load_waveform((u8 *) par->firmware->data, par->firmware->size, - par->current_wf_mode, val, par); - } - - return ret; -} - -DEVICE_ATTR(defio_delay, 0644, - metronomefb_defio_delay_show, metronomefb_defio_delay_store); -DEVICE_ATTR(manual_refresh_threshold, 0644, - metronomefb_manual_refresh_thr_show, metronomefb_manual_refresh_thr_store); -DEVICE_ATTR(temp, 0644, - metronomefb_temp_show, metronomefb_temp_store); -DEVICE_ATTR(autorefresh_interval, 0644, - metronomefb_autorefresh_interval_show, metronomefb_autorefresh_interval_store); - - -static int __devinit metronomefb_probe(struct platform_device *dev) -{ - struct fb_info *info; - struct metronome_board *board; - int retval = -ENOMEM; - int videomemorysize; - unsigned char *videomemory; - struct metronomefb_par *par; - const struct firmware *fw_entry; - int i; - int panel_type; - int fw, fh; - int epd_dt_index; - - /* pick up board specific routines */ - board = dev->dev.platform_data; - if (!board) - return -EINVAL; - - /* try to count device specific driver, if can't, platform recalls */ - if (!try_module_get(board->owner)) - return -ENODEV; - - info = framebuffer_alloc(sizeof(struct metronomefb_par), &dev->dev); - if (!info) - goto err; - - /* we have two blocks of memory. - info->screen_base which is vm, and is the fb used by apps. - par->metromem which is physically contiguous memory and - contains the display controller commands, waveform, - processed image data and padding. this is the data pulled - by the device's LCD controller and pushed to Metronome. - the metromem memory is allocated by the board driver and - is provided to us */ - - panel_type = board->get_panel_type(); - switch (panel_type) { - case 5: - epd_dt_index = 3; - break; - case 6: - epd_dt_index = 0; - break; - case 8: - epd_dt_index = 1; - break; - case 97: - epd_dt_index = 2; - break; - default: - dev_err(&dev->dev, "Unexpected panel type. Defaulting to 6\n"); - epd_dt_index = 0; - break; - } - - fw = epd_frame_table[epd_dt_index].fw; - fh = epd_frame_table[epd_dt_index].fh; - - /* we need to add a spare page because our csum caching scheme walks - * to the end of the page */ - videomemorysize = PAGE_SIZE + (fw * fh); - videomemory = vmalloc(videomemorysize); - if (!videomemory) - goto err_fb_rel; - - memset(videomemory, 0xff, videomemorysize); - - info->screen_base = (char __force __iomem *)videomemory; - info->fbops = &metronomefb_ops; - - info->var = metronomefb_var; - info->var.xres = fw; - info->var.yres = fh; - info->var.xres_virtual = fw; - info->var.yres_virtual = fh; - info->fix = metronomefb_fix; - info->fix.line_length = fw; - info->fix.smem_len = fw * fh; /* Real size of image area */ - par = info->par; - par->info = info; - par->board = board; - par->epd_frame = &epd_frame_table[epd_dt_index]; - par->pdev = dev; - - par->fxbuckets = kmalloc((fw / 4 + 1) * sizeof(*par->fxbuckets), GFP_KERNEL); - if (!par->fxbuckets) - goto err_vfree; - - par->fybuckets = kmalloc(fh * sizeof(*par->fybuckets), GFP_KERNEL); - if (!par->fybuckets) - goto err_fxbuckets; - - init_waitqueue_head(&par->waitq); - par->manual_refresh_threshold = 60; - par->partial_autorefresh_interval = 256; - par->partial_updates_count = 0; - par->is_first_update = 1; - mutex_init(&par->lock); - - /* this table caches per page csum values. */ - par->csum_table = vmalloc(videomemorysize/PAGE_SIZE); - if (!par->csum_table) - goto err_fybuckets; - - /* the physical framebuffer that we use is setup by - * the platform device driver. It will provide us - * with cmd, wfm and image memory in a contiguous area. */ - retval = board->setup_fb(par); - if (retval) { - dev_err(&dev->dev, "Failed to setup fb\n"); - goto err_csum_table; - } - - /* after this point we should have a framebuffer */ - if ((!par->metromem_wfm) || (!par->metromem_img) || - (!par->metromem_dma)) { - dev_err(&dev->dev, "fb access failure\n"); - retval = -EINVAL; - goto err_csum_table; - } - - info->fix.smem_start = par->metromem_dma; - - /* load the waveform in. assume mode 3, temp 31 for now - a) request the waveform file from userspace - b) process waveform and decode into metromem */ - retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); - if (retval < 0) { - dev_err(&dev->dev, "Failed to get waveform\n"); - goto err_csum_table; - } - - retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, WF_MODE_GC, temp, - par); - if (retval < 0) { - dev_err(&dev->dev, "Failed processing waveform\n"); - goto err_csum_table; - } - par->firmware = fw_entry; - - retval = board->setup_io(par); - if (retval) { - dev_err(&dev->dev, "metronomefb: setup_io() failed\n"); - goto err_csum_table; - } - - if (board->setup_irq(info)) - goto err_csum_table; - - retval = metronome_init_regs(par); - if (retval < 0) - goto err_free_irq; - - info->flags = FBINFO_FLAG_DEFAULT; - - info->fbdefio = &metronomefb_defio; - fb_deferred_io_init(info); - - retval = fb_alloc_cmap(&info->cmap, 8, 0); - if (retval < 0) { - dev_err(&dev->dev, "Failed to allocate colormap\n"); - goto err_free_irq; - } - - /* set cmap */ - for (i = 0; i < 8; i++) - info->cmap.red[i] = ((2 * i + 1)*(0xFFFF))/16; - memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8); - memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8); - - retval = register_framebuffer(info); - if (retval < 0) - goto err_cmap; - - platform_set_drvdata(dev, info); - - retval = device_create_file(info->dev, &dev_attr_defio_delay); - if (retval) - goto err_devattr_defio_delay; - - retval = device_create_file(info->dev, &dev_attr_manual_refresh_threshold); - if (retval) - goto err_devattr_manual_refresh_thr; - - retval = device_create_file(info->dev, &dev_attr_temp); - if (retval) - goto err_devattr_temp; - - retval = device_create_file(info->dev, &dev_attr_autorefresh_interval); - if (retval) - goto err_devattr_autorefresh; - - dev_info(&dev->dev, - "fb%d: Metronome frame buffer device, using %dK of video" - " memory\n", info->node, videomemorysize >> 10); - - return 0; - - device_remove_file(info->dev, &dev_attr_autorefresh_interval); -err_devattr_autorefresh: - device_remove_file(info->dev, &dev_attr_temp); -err_devattr_temp: - device_remove_file(info->dev, &dev_attr_manual_refresh_threshold); -err_devattr_manual_refresh_thr: - device_remove_file(info->dev, &dev_attr_defio_delay); -err_devattr_defio_delay: - unregister_framebuffer(info); -err_cmap: - fb_dealloc_cmap(&info->cmap); -err_free_irq: - board->cleanup(par); -err_csum_table: - vfree(par->csum_table); -err_fybuckets: - kfree(par->fybuckets); -err_fxbuckets: - kfree(par->fxbuckets); -err_vfree: - vfree(videomemory); -err_fb_rel: - framebuffer_release(info); -err: - module_put(board->owner); - return retval; -} - -static int __devexit metronomefb_remove(struct platform_device *dev) -{ - struct fb_info *info = platform_get_drvdata(dev); - - if (info) { - struct metronomefb_par *par = info->par; - - par->board->set_stdby(par, 0); - mdelay(1); - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_OFF); - - device_remove_file(info->dev, &dev_attr_autorefresh_interval); - device_remove_file(info->dev, &dev_attr_temp); - device_remove_file(info->dev, &dev_attr_manual_refresh_threshold); - device_remove_file(info->dev, &dev_attr_defio_delay); - unregister_framebuffer(info); - fb_deferred_io_cleanup(info); - fb_dealloc_cmap(&info->cmap); - par->board->cleanup(par); - vfree(par->csum_table); - kfree(par->fybuckets); - kfree(par->fxbuckets); - vfree((void __force *)info->screen_base); - module_put(par->board->owner); - release_firmware(par->firmware); - dev_dbg(&dev->dev, "calling release\n"); - framebuffer_release(info); - } - return 0; -} - -#ifdef CONFIG_PM -static int metronomefb_suspend(struct platform_device *pdev, pm_message_t message) -{ - struct fb_info *info = platform_get_drvdata(pdev); - struct metronomefb_par *par = info->par; - - par->board->set_stdby(par, 0); - par->board->set_rst(par, 0); - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_OFF); - - - return 0; -} - -static int metronomefb_resume(struct platform_device *pdev) -{ - struct fb_info *info = platform_get_drvdata(pdev); - struct metronomefb_par *par = info->par; - - if (par->board->power_ctl) - par->board->power_ctl(par, METRONOME_POWER_ON); - - mutex_lock(&par->lock); - metronome_bootup(par); - mutex_unlock(&par->lock); - - return 0; -} - -#else -#define metronomefb_suspend NULL -#define metronomefb_resume NULL -#endif - - -static struct platform_driver metronomefb_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "metronomefb", - }, - .probe = metronomefb_probe, - .remove = __devexit_p(metronomefb_remove), - .suspend = metronomefb_suspend, - .resume = metronomefb_resume, -}; - -static int __init metronomefb_init(void) -{ - return platform_driver_register(&metronomefb_driver); -} - -static void __exit metronomefb_exit(void) -{ - platform_driver_unregister(&metronomefb_driver); -} - -module_param(temp, int, 0); -MODULE_PARM_DESC(temp, "Set current temperature"); - -module_init(metronomefb_init); -module_exit(metronomefb_exit); - -MODULE_DESCRIPTION("fbdev driver for Metronome controller"); -MODULE_AUTHOR("Jaya Kumar"); -MODULE_LICENSE("GPL"); |