Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
395e9801
Commit
395e9801
authored
Dec 08, 2009
by
Kevin Hilman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'davinci-upstream-accepted' into davinci-reset
parents
ca3e7676
9e56b56d
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1273 additions
and
27 deletions
+1273
-27
arch/arm/mach-davinci/include/mach/keyscan.h
arch/arm/mach-davinci/include/mach/keyscan.h
+41
-0
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Kconfig
+10
-0
drivers/input/keyboard/Makefile
drivers/input/keyboard/Makefile
+1
-0
drivers/input/keyboard/davinci_keyscan.c
drivers/input/keyboard/davinci_keyscan.c
+337
-0
drivers/mtd/mtdpart.c
drivers/mtd/mtdpart.c
+40
-0
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/davinci_nand.c
+1
-1
drivers/rtc/Kconfig
drivers/rtc/Kconfig
+10
-0
drivers/rtc/Makefile
drivers/rtc/Makefile
+1
-0
drivers/rtc/rtc-davinci.c
drivers/rtc/rtc-davinci.c
+673
-0
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-omap.c
+0
-5
drivers/video/da8xx-fb.c
drivers/video/da8xx-fb.c
+155
-21
include/linux/mtd/partitions.h
include/linux/mtd/partitions.h
+3
-0
include/video/da8xx-fb.h
include/video/da8xx-fb.h
+1
-0
No files found.
arch/arm/mach-davinci/include/mach/keyscan.h
0 → 100644
View file @
395e9801
/*
* Copyright (C) 2009 Texas Instruments, Inc
*
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DAVINCI_KEYSCAN_H
#define DAVINCI_KEYSCAN_H
#include <linux/io.h>
enum
davinci_matrix_types
{
DAVINCI_KEYSCAN_MATRIX_4X4
,
DAVINCI_KEYSCAN_MATRIX_5X3
,
};
struct
davinci_ks_platform_data
{
unsigned
short
*
keymap
;
u32
keymapsize
;
u8
rep
:
1
;
u8
strobe
;
u8
interval
;
u8
matrix_type
;
};
#endif
drivers/input/keyboard/Kconfig
View file @
395e9801
...
...
@@ -423,4 +423,14 @@ config KEYBOARD_W90P910
To compile this driver as a module, choose M here: the
module will be called w90p910_keypad.
config KEYBOARD_DAVINCI
tristate "TI DaVinci Key Scan"
depends on ARCH_DAVINCI_DM365
help
Say Y to enable keypad module support for the TI DaVinci
platforms (DM365).
To compile this driver as a module, choose M here: the
module will be called davinci_keyscan.
endif
drivers/input/keyboard/Makefile
View file @
395e9801
...
...
@@ -37,3 +37,4 @@ obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
obj-$(CONFIG_KEYBOARD_TWL4030)
+=
twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD)
+=
xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910)
+=
w90p910_keypad.o
obj-$(CONFIG_KEYBOARD_DAVINCI)
+=
davinci_keyscan.o
drivers/input/keyboard/davinci_keyscan.c
0 → 100644
View file @
395e9801
/*
* DaVinci Key Scan Driver for TI platforms
*
* Copyright (C) 2009 Texas Instruments, Inc
*
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
*
* Intial Code: Sandeep Paulraj <s-paulraj@ti.com>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/errno.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/keyscan.h>
/* Key scan registers */
#define DAVINCI_KEYSCAN_KEYCTRL 0x0000
#define DAVINCI_KEYSCAN_INTENA 0x0004
#define DAVINCI_KEYSCAN_INTFLAG 0x0008
#define DAVINCI_KEYSCAN_INTCLR 0x000c
#define DAVINCI_KEYSCAN_STRBWIDTH 0x0010
#define DAVINCI_KEYSCAN_INTERVAL 0x0014
#define DAVINCI_KEYSCAN_CONTTIME 0x0018
#define DAVINCI_KEYSCAN_CURRENTST 0x001c
#define DAVINCI_KEYSCAN_PREVSTATE 0x0020
#define DAVINCI_KEYSCAN_EMUCTRL 0x0024
#define DAVINCI_KEYSCAN_IODFTCTRL 0x002c
/* Key Control Register (KEYCTRL) */
#define DAVINCI_KEYSCAN_KEYEN 0x00000001
#define DAVINCI_KEYSCAN_PREVMODE 0x00000002
#define DAVINCI_KEYSCAN_CHATOFF 0x00000004
#define DAVINCI_KEYSCAN_AUTODET 0x00000008
#define DAVINCI_KEYSCAN_SCANMODE 0x00000010
#define DAVINCI_KEYSCAN_OUTTYPE 0x00000020
/* Masks for the interrupts */
#define DAVINCI_KEYSCAN_INT_CONT 0x00000008
#define DAVINCI_KEYSCAN_INT_OFF 0x00000004
#define DAVINCI_KEYSCAN_INT_ON 0x00000002
#define DAVINCI_KEYSCAN_INT_CHANGE 0x00000001
#define DAVINCI_KEYSCAN_INT_ALL 0x0000000f
struct
davinci_ks
{
struct
input_dev
*
input
;
struct
davinci_ks_platform_data
*
pdata
;
int
irq
;
void
__iomem
*
base
;
resource_size_t
pbase
;
size_t
base_size
;
unsigned
short
keymap
[];
};
/* Initializing the kp Module */
static
int
__init
davinci_ks_initialize
(
struct
davinci_ks
*
davinci_ks
)
{
struct
device
*
dev
=
&
davinci_ks
->
input
->
dev
;
struct
davinci_ks_platform_data
*
pdata
=
davinci_ks
->
pdata
;
u32
matrix_ctrl
;
/* Enable all interrupts */
__raw_writel
(
DAVINCI_KEYSCAN_INT_ALL
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTENA
);
/* Clear interrupts if any */
__raw_writel
(
DAVINCI_KEYSCAN_INT_ALL
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTCLR
);
/* Setup the scan period = strobe + interval */
__raw_writel
(
pdata
->
strobe
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_STRBWIDTH
);
__raw_writel
(
pdata
->
interval
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTERVAL
);
__raw_writel
(
0x01
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_CONTTIME
);
/* Define matrix type */
switch
(
pdata
->
matrix_type
)
{
case
DAVINCI_KEYSCAN_MATRIX_4X4
:
matrix_ctrl
=
0
;
break
;
case
DAVINCI_KEYSCAN_MATRIX_5X3
:
matrix_ctrl
=
(
1
<<
6
);
break
;
default:
dev_err
(
dev
->
parent
,
"wrong matrix type
\n
"
);
return
-
EINVAL
;
}
/* Enable key scan module and set matrix type */
__raw_writel
(
DAVINCI_KEYSCAN_AUTODET
|
DAVINCI_KEYSCAN_KEYEN
|
matrix_ctrl
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_KEYCTRL
);
return
0
;
}
static
irqreturn_t
davinci_ks_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
davinci_ks
*
davinci_ks
=
dev_id
;
struct
device
*
dev
=
&
davinci_ks
->
input
->
dev
;
unsigned
short
*
keymap
=
davinci_ks
->
keymap
;
int
keymapsize
=
davinci_ks
->
pdata
->
keymapsize
;
u32
prev_status
,
new_status
,
changed
;
bool
release
;
int
keycode
=
KEY_UNKNOWN
;
int
i
;
/* Disable interrupt */
__raw_writel
(
0x0
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTENA
);
/* Reading previous and new status of the key scan */
prev_status
=
__raw_readl
(
davinci_ks
->
base
+
DAVINCI_KEYSCAN_PREVSTATE
);
new_status
=
__raw_readl
(
davinci_ks
->
base
+
DAVINCI_KEYSCAN_CURRENTST
);
changed
=
prev_status
^
new_status
;
if
(
changed
)
{
/*
* It goes through all bits in 'changed' to ensure
* that no key changes are being missed
*/
for
(
i
=
0
;
i
<
keymapsize
;
i
++
)
{
if
((
changed
>>
i
)
&
0x1
)
{
keycode
=
keymap
[
i
];
release
=
(
new_status
>>
i
)
&
0x1
;
dev_dbg
(
dev
->
parent
,
"key %d %s
\n
"
,
keycode
,
release
?
"released"
:
"pressed"
);
input_report_key
(
davinci_ks
->
input
,
keycode
,
!
release
);
input_sync
(
davinci_ks
->
input
);
}
}
/* Clearing interrupt */
__raw_writel
(
DAVINCI_KEYSCAN_INT_ALL
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTCLR
);
}
/* Enable interrupts */
__raw_writel
(
0x1
,
davinci_ks
->
base
+
DAVINCI_KEYSCAN_INTENA
);
return
IRQ_HANDLED
;
}
static
int
__init
davinci_ks_probe
(
struct
platform_device
*
pdev
)
{
struct
davinci_ks
*
davinci_ks
;
struct
input_dev
*
key_dev
;
struct
resource
*
res
,
*
mem
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
davinci_ks_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
int
error
,
i
;
if
(
!
pdata
->
keymap
)
{
dev_dbg
(
dev
,
"no keymap from pdata
\n
"
);
return
-
EINVAL
;
}
davinci_ks
=
kzalloc
(
sizeof
(
struct
davinci_ks
)
+
sizeof
(
unsigned
short
)
*
pdata
->
keymapsize
,
GFP_KERNEL
);
if
(
!
davinci_ks
)
{
dev_dbg
(
dev
,
"could not allocate memory for private data
\n
"
);
return
-
ENOMEM
;
}
memcpy
(
davinci_ks
->
keymap
,
pdata
->
keymap
,
sizeof
(
unsigned
short
)
*
pdata
->
keymapsize
);
key_dev
=
input_allocate_device
();
if
(
!
key_dev
)
{
dev_dbg
(
dev
,
"could not allocate input device
\n
"
);
error
=
-
ENOMEM
;
goto
fail1
;
}
davinci_ks
->
input
=
key_dev
;
davinci_ks
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
davinci_ks
->
irq
<
0
)
{
dev_err
(
dev
,
"no key scan irq
\n
"
);
error
=
davinci_ks
->
irq
;
goto
fail2
;
}
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
{
dev_err
(
dev
,
"no mem resource
\n
"
);
error
=
-
EINVAL
;
goto
fail2
;
}
davinci_ks
->
pbase
=
res
->
start
;
davinci_ks
->
base_size
=
resource_size
(
res
);
mem
=
request_mem_region
(
davinci_ks
->
pbase
,
davinci_ks
->
base_size
,
pdev
->
name
);
if
(
!
mem
)
{
dev_err
(
dev
,
"key scan registers at %08x are not free
\n
"
,
davinci_ks
->
pbase
);
error
=
-
EBUSY
;
goto
fail2
;
}
davinci_ks
->
base
=
ioremap
(
davinci_ks
->
pbase
,
davinci_ks
->
base_size
);
if
(
!
davinci_ks
->
base
)
{
dev_err
(
dev
,
"can't ioremap MEM resource.
\n
"
);
error
=
-
ENOMEM
;
goto
fail3
;
}
/* Enable auto repeat feature of Linux input subsystem */
if
(
pdata
->
rep
)
__set_bit
(
EV_REP
,
key_dev
->
evbit
);
/* Setup input device */
__set_bit
(
EV_KEY
,
key_dev
->
evbit
);
/* Setup the platform data */
davinci_ks
->
pdata
=
pdata
;
for
(
i
=
0
;
i
<
davinci_ks
->
pdata
->
keymapsize
;
i
++
)
__set_bit
(
davinci_ks
->
pdata
->
keymap
[
i
],
key_dev
->
keybit
);
key_dev
->
name
=
"davinci_keyscan"
;
key_dev
->
phys
=
"davinci_keyscan/input0"
;
key_dev
->
dev
.
parent
=
&
pdev
->
dev
;
key_dev
->
id
.
bustype
=
BUS_HOST
;
key_dev
->
id
.
vendor
=
0x0001
;
key_dev
->
id
.
product
=
0x0001
;
key_dev
->
id
.
version
=
0x0001
;
key_dev
->
keycode
=
davinci_ks
->
keymap
;
key_dev
->
keycodesize
=
sizeof
(
davinci_ks
->
keymap
[
0
]);
key_dev
->
keycodemax
=
davinci_ks
->
pdata
->
keymapsize
;
error
=
input_register_device
(
davinci_ks
->
input
);
if
(
error
<
0
)
{
dev_err
(
dev
,
"unable to register davinci key scan device
\n
"
);
goto
fail4
;
}
error
=
request_irq
(
davinci_ks
->
irq
,
davinci_ks_interrupt
,
IRQF_DISABLED
,
pdev
->
name
,
davinci_ks
);
if
(
error
<
0
)
{
dev_err
(
dev
,
"unable to register davinci key scan interrupt
\n
"
);
goto
fail5
;
}
error
=
davinci_ks_initialize
(
davinci_ks
);
if
(
error
<
0
)
{
dev_err
(
dev
,
"unable to initialize davinci key scan device
\n
"
);
goto
fail6
;
}
platform_set_drvdata
(
pdev
,
davinci_ks
);
return
0
;
fail6:
free_irq
(
davinci_ks
->
irq
,
davinci_ks
);
fail5:
input_unregister_device
(
davinci_ks
->
input
);
key_dev
=
NULL
;
fail4:
iounmap
(
davinci_ks
->
base
);
fail3:
release_mem_region
(
davinci_ks
->
pbase
,
davinci_ks
->
base_size
);
fail2:
input_free_device
(
key_dev
);
fail1:
kfree
(
davinci_ks
);
return
error
;
}
static
int
__devexit
davinci_ks_remove
(
struct
platform_device
*
pdev
)
{
struct
davinci_ks
*
davinci_ks
=
platform_get_drvdata
(
pdev
);
free_irq
(
davinci_ks
->
irq
,
davinci_ks
);
input_unregister_device
(
davinci_ks
->
input
);
iounmap
(
davinci_ks
->
base
);
release_mem_region
(
davinci_ks
->
pbase
,
davinci_ks
->
base_size
);
platform_set_drvdata
(
pdev
,
NULL
);
kfree
(
davinci_ks
);
return
0
;
}
static
struct
platform_driver
davinci_ks_driver
=
{
.
driver
=
{
.
name
=
"davinci_keyscan"
,
.
owner
=
THIS_MODULE
,
},
.
remove
=
__devexit_p
(
davinci_ks_remove
),
};
static
int
__init
davinci_ks_init
(
void
)
{
return
platform_driver_probe
(
&
davinci_ks_driver
,
davinci_ks_probe
);
}
module_init
(
davinci_ks_init
);
static
void
__exit
davinci_ks_exit
(
void
)
{
platform_driver_unregister
(
&
davinci_ks_driver
);
}
module_exit
(
davinci_ks_exit
);
MODULE_AUTHOR
(
"Miguel Aguilar"
);
MODULE_DESCRIPTION
(
"Texas Instruments DaVinci Key Scan Driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/mtd/mtdpart.c
View file @
395e9801
...
...
@@ -26,6 +26,7 @@ static LIST_HEAD(mtd_partitions);
struct
mtd_part
{
struct
mtd_info
mtd
;
struct
mtd_info
*
master
;
struct
memory_accessor
macc
;
uint64_t
offset
;
struct
list_head
list
;
};
...
...
@@ -327,6 +328,39 @@ int del_mtd_partitions(struct mtd_info *master)
}
EXPORT_SYMBOL
(
del_mtd_partitions
);
/*
* This lets other kernel code access the flash data. For example, it
* might hold a board's Ethernet address, or board-specific calibration
* data generated on the manufacturing floor.
*/
static
ssize_t
mtd_macc_read
(
struct
memory_accessor
*
macc
,
char
*
buf
,
off_t
offset
,
size_t
count
)
{
struct
mtd_part
*
part
=
container_of
(
macc
,
struct
mtd_part
,
macc
);
ssize_t
ret
=
-
EIO
;
size_t
retlen
;
if
(
part_read
((
struct
mtd_info
*
)
part
,
offset
,
count
,
&
retlen
,
buf
)
==
0
)
ret
=
retlen
;
return
ret
;
}
static
ssize_t
mtd_macc_write
(
struct
memory_accessor
*
macc
,
const
char
*
buf
,
off_t
offset
,
size_t
count
)
{
struct
mtd_part
*
part
=
container_of
(
macc
,
struct
mtd_part
,
macc
);
ssize_t
ret
=
-
EIO
;
size_t
retlen
;
if
(
part_write
((
struct
mtd_info
*
)
part
,
offset
,
count
,
&
retlen
,
buf
)
==
0
)
ret
=
retlen
;
return
ret
;
}
static
struct
mtd_part
*
add_one_partition
(
struct
mtd_info
*
master
,
const
struct
mtd_partition
*
part
,
int
partno
,
uint64_t
cur_offset
)
...
...
@@ -364,6 +398,9 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave
->
mtd
.
read
=
part_read
;
slave
->
mtd
.
write
=
part_write
;
slave
->
macc
.
read
=
mtd_macc_read
;
slave
->
macc
.
write
=
mtd_macc_write
;
if
(
master
->
panic_write
)
slave
->
mtd
.
panic_write
=
part_panic_write
;
...
...
@@ -428,6 +465,9 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
printk
(
KERN_NOTICE
"0x%012llx-0x%012llx :
\"
%s
\"\n
"
,
(
unsigned
long
long
)
slave
->
offset
,
(
unsigned
long
long
)(
slave
->
offset
+
slave
->
mtd
.
size
),
slave
->
mtd
.
name
);
if
(
part
->
setup
)
part
->
setup
(
&
slave
->
macc
,
(
void
*
)
part
->
context
);
/* let's do some sanity checks */
if
(
slave
->
offset
>=
master
->
size
)
{
/* let's register it anyway to preserve ordering */
...
...
drivers/mtd/nand/davinci_nand.c
View file @
395e9801
...
...
@@ -599,7 +599,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
info
->
mask_chipsel
=
pdata
->
mask_chipsel
;
/* use nandboot-capable ALE/CLE masks by default */
info
->
mask_ale
=
pdata
->
mask_
c
le
?
:
MASK_ALE
;
info
->
mask_ale
=
pdata
->
mask_
a
le
?
:
MASK_ALE
;
info
->
mask_cle
=
pdata
->
mask_cle
?
:
MASK_CLE
;
/* Set address of hardware control function */
...
...
drivers/rtc/Kconfig
View file @
395e9801
...
...
@@ -576,6 +576,16 @@ config RTC_DRV_AB3100
comment "on-CPU RTC drivers"
config RTC_DRV_DAVINCI
tristate "TI DaVinci RTC"
depends on ARCH_DAVINCI_DM365
help
If you say yes here you get support for the RTC on the
DaVinci platforms (DM365).
This driver can also be built as a module. If so, the module
will be called rtc-davinci.
config RTC_DRV_OMAP
tristate "TI OMAP1"
depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730
...
...
drivers/rtc/Makefile
View file @
395e9801
...
...
@@ -26,6 +26,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
obj-$(CONFIG_RTC_DRV_BQ4802)
+=
rtc-bq4802.o
obj-$(CONFIG_RTC_DRV_CMOS)
+=
rtc-cmos.o
obj-$(CONFIG_RTC_DRV_COH901331)
+=
rtc-coh901331.o
obj-$(CONFIG_RTC_DRV_DAVINCI)
+=
rtc-davinci.o
obj-$(CONFIG_RTC_DRV_DM355EVM)
+=
rtc-dm355evm.o
obj-$(CONFIG_RTC_DRV_DS1216)
+=
rtc-ds1216.o
obj-$(CONFIG_RTC_DRV_DS1286)
+=
rtc-ds1286.o
...
...
drivers/rtc/rtc-davinci.c
0 → 100644
View file @
395e9801
This diff is collapsed.
Click to expand it.
drivers/rtc/rtc-omap.c
View file @
395e9801
...
...
@@ -399,17 +399,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
new_ctrl
|=
OMAP_RTC_CTRL_STOP
;
/* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
*
* - Boards wired so that RTC_WAKE_INT does something, and muxed
* right (W13_1610_RTC_WAKE_INT is the default after chip reset),
* should initialize the device wakeup flag appropriately.
*
* - Boards wired so RTC_ON_nOFF is used as the reset signal,
* rather than nPWRON_RESET, should forcibly enable split
* power mode. (Some chip errata report that RTC_CTRL_SPLIT
* is write-only, and always reads as zero...)
*/
device_init_wakeup
(
&
pdev
->
dev
,
0
);
if
(
new_ctrl
&
(
u8
)
OMAP_RTC_CTRL_SPLIT
)
pr_info
(
"%s: split power mode
\n
"
,
pdev
->
name
);
...
...
drivers/video/da8xx-fb.c
View file @
395e9801
...
...
@@ -28,6 +28,8 @@
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/console.h>
#include <video/da8xx-fb.h>
#define DRIVER_NAME "da8xx_lcdc"
...
...
@@ -113,6 +115,12 @@ struct da8xx_fb_par {
unsigned
short
pseudo_palette
[
16
];
unsigned
int
databuf_sz
;
unsigned
int
palette_sz
;
unsigned
int
pxl_clk
;
int
blank
;
#ifdef CONFIG_CPU_FREQ
struct
notifier_block
freq_transition
;
#endif
void
(
*
panel_power_ctrl
)(
int
);
};
/* Variable Screen Information */
...
...
@@ -155,7 +163,7 @@ struct da8xx_panel {
int
vfp
;
/* Vertical front porch */
int
vbp
;
/* Vertical back porch */
int
vsw
;
/* Vertical Sync Pulse Width */
int
pxl_clk
;
/* Pixel clock */
unsigned
int
pxl_clk
;
/* Pixel clock */
unsigned
char
invert_pxl_clk
;
/* Invert Pixel clock */
};
...
...
@@ -171,7 +179,7 @@ static struct da8xx_panel known_lcd_panels[] = {
.
vfp
=
2
,
.
vbp
=
2
,
.
vsw
=
0
,
.
pxl_clk
=
0x1
0
,
.
pxl_clk
=
460800
0
,
.
invert_pxl_clk
=
1
,
},
/* Sharp LK043T1DG01 */
...
...
@@ -185,13 +193,23 @@ static struct da8xx_panel known_lcd_panels[] = {
.
vfp
=
2
,
.
vbp
=
2
,
.
vsw
=
10
,
.
pxl_clk
=
0x12
,
.
pxl_clk
=
7833600
,
.
invert_pxl_clk
=
0
,
},
};
/* Enable the Raster Engine of the LCD Controller */
static
inline
void
lcd_enable_raster
(
void
)
{
u32
reg
;
reg
=
lcdc_read
(
LCD_RASTER_CTRL_REG
);
if
(
!
(
reg
&
LCD_RASTER_ENABLE
))
lcdc_write
(
reg
|
LCD_RASTER_ENABLE
,
LCD_RASTER_CTRL_REG
);
}
/* Disable the Raster Engine of the LCD Controller */
static
void
lcd_disable_raster
(
struct
da8xx_fb_par
*
par
)
static
inline
void
lcd_disable_raster
(
void
)
{
u32
reg
;
...
...
@@ -443,25 +461,36 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
static
void
lcd_reset
(
struct
da8xx_fb_par
*
par
)
{
/* Disable the Raster if previously Enabled */
if
(
lcdc_read
(
LCD_RASTER_CTRL_REG
)
&
LCD_RASTER_ENABLE
)
lcd_disable_raster
(
par
);
lcd_disable_raster
();
/* DMA has to be disabled */
lcdc_write
(
0
,
LCD_DMA_CTRL_REG
);
lcdc_write
(
0
,
LCD_RASTER_CTRL_REG
);
}
static
void
lcd_calc_clk_divider
(
struct
da8xx_fb_par
*
par
)
{
unsigned
int
lcd_clk
,
div
;
lcd_clk
=
clk_get_rate
(
par
->
lcdc_clk
);
div
=
lcd_clk
/
par
->
pxl_clk
;
/* Configure the LCD clock divisor. */
lcdc_write
(
LCD_CLK_DIVISOR
(
div
)
|
(
LCD_RASTER_MODE
&
0x1
),
LCD_CTRL_REG
);
}
static
int
lcd_init
(
struct
da8xx_fb_par
*
par
,
const
struct
lcd_ctrl_config
*
cfg
,
struct
da8xx_panel
*
panel
)
{
u32
bpp
;
int
ret
=
0
;
unsigned
int
lcd_clk
,
div
;
lcd_reset
(
par
);
/* Configure the LCD clock divisor. */
lcdc_write
(
LCD_CLK_DIVISOR
(
panel
->
pxl_clk
)
|
(
LCD_RASTER_MODE
&
0x1
),
LCD_CTRL_REG
);
/* Calculate the divider */
lcd_calc_clk_divider
(
par
);
if
(
panel
->
invert_pxl_clk
)
lcdc_write
((
lcdc_read
(
LCD_RASTER_TIMING_2_REG
)
|
...
...
@@ -513,13 +542,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
static
irqreturn_t
lcdc_irq_handler
(
int
irq
,
void
*
arg
)
{
u32
stat
=
lcdc_read
(
LCD_STAT_REG
);
u32
reg
;
if
((
stat
&
LCD_SYNC_LOST
)
&&
(
stat
&
LCD_FIFO_UNDERFLOW
))
{
reg
=
lcdc_read
(
LCD_RASTER_CTRL_REG
);
lcdc_write
(
reg
&
~
LCD_RASTER_ENABLE
,
LCD_RASTER_CTRL_REG
);
lcd_disable_raster
();
lcdc_write
(
stat
,
LCD_STAT_REG
);
lcd
c_write
(
reg
|
LCD_RASTER_ENABLE
,
LCD_RASTER_CTRL_REG
);
lcd
_enable_raster
(
);
}
else
lcdc_write
(
stat
,
LCD_STAT_REG
);
...
...
@@ -574,6 +601,38 @@ static int fb_check_var(struct fb_var_screeninfo *var,
return
err
;
}
#ifdef CONFIG_CPU_FREQ
static
int
lcd_da8xx_cpufreq_transition
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
struct
da8xx_fb_par
*
par
;
par
=
container_of
(
nb
,
struct
da8xx_fb_par
,
freq_transition
);
if
(
val
==
CPUFREQ_PRECHANGE
)
{
lcd_disable_raster
();
}
else
if
(
val
==
CPUFREQ_POSTCHANGE
)
{
lcd_calc_clk_divider
(
par
);
lcd_enable_raster
();
}
return
0
;
}
static
inline
int
lcd_da8xx_cpufreq_register
(
struct
da8xx_fb_par
*
par
)
{
par
->
freq_transition
.
notifier_call
=
lcd_da8xx_cpufreq_transition
;
return
cpufreq_register_notifier
(
&
par
->
freq_transition
,
CPUFREQ_TRANSITION_NOTIFIER
);
}
static
inline
void
lcd_da8xx_cpufreq_deregister
(
struct
da8xx_fb_par
*
par
)
{
cpufreq_unregister_notifier
(
&
par
->
freq_transition
,
CPUFREQ_TRANSITION_NOTIFIER
);
}
#endif
static
int
__devexit
fb_remove
(
struct
platform_device
*
dev
)
{
struct
fb_info
*
info
=
dev_get_drvdata
(
&
dev
->
dev
);
...
...
@@ -581,8 +640,13 @@ static int __devexit fb_remove(struct platform_device *dev)
if
(
info
)
{
struct
da8xx_fb_par
*
par
=
info
->
par
;
if
(
lcdc_read
(
LCD_RASTER_CTRL_REG
)
&
LCD_RASTER_ENABLE
)
lcd_disable_raster
(
par
);
#ifdef CONFIG_CPU_FREQ
lcd_da8xx_cpufreq_deregister
(
par
);
#endif
if
(
par
->
panel_power_ctrl
)
par
->
panel_power_ctrl
(
0
);
lcd_disable_raster
();
lcdc_write
(
0
,
LCD_RASTER_CTRL_REG
);
/* disable DMA */
...
...
@@ -639,6 +703,35 @@ static int fb_ioctl(struct fb_info *info, unsigned int cmd,
return
0
;
}
static
int
cfb_blank
(
int
blank
,
struct
fb_info
*
info
)
{
struct
da8xx_fb_par
*
par
=
info
->
par
;
int
ret
=
0
;
if
(
par
->
blank
==
blank
)
return
0
;
par
->
blank
=
blank
;
switch
(
blank
)
{
case
FB_BLANK_UNBLANK
:
if
(
par
->
panel_power_ctrl
)
par
->
panel_power_ctrl
(
1
);
lcd_enable_raster
();
break
;
case
FB_BLANK_POWERDOWN
:
if
(
par
->
panel_power_ctrl
)
par
->
panel_power_ctrl
(
0
);
lcd_disable_raster
();
break
;
default:
ret
=
-
EINVAL
;
}
return
ret
;
}
static
struct
fb_ops
da8xx_fb_ops
=
{
.
owner
=
THIS_MODULE
,
.
fb_check_var
=
fb_check_var
,
...
...
@@ -647,6 +740,7 @@ static struct fb_ops da8xx_fb_ops = {
.
fb_fillrect
=
cfb_fillrect
,
.
fb_copyarea
=
cfb_copyarea
,
.
fb_imageblit
=
cfb_imageblit
,
.
fb_blank
=
cfb_blank
,
};
static
int
__init
fb_probe
(
struct
platform_device
*
device
)
...
...
@@ -721,6 +815,12 @@ static int __init fb_probe(struct platform_device *device)
}
par
=
da8xx_fb_info
->
par
;
par
->
lcdc_clk
=
fb_clk
;
par
->
pxl_clk
=
lcdc_info
->
pxl_clk
;
if
(
fb_pdata
->
panel_power_ctrl
)
{
par
->
panel_power_ctrl
=
fb_pdata
->
panel_power_ctrl
;
par
->
panel_power_ctrl
(
1
);
}
if
(
lcd_init
(
par
,
lcd_cfg
,
lcdc_info
)
<
0
)
{
dev_err
(
&
device
->
dev
,
"lcd_init failed
\n
"
);
...
...
@@ -754,8 +854,6 @@ static int __init fb_probe(struct platform_device *device)
da8xx_fb_fix
.
smem_len
=
par
->
databuf_sz
-
par
->
palette_sz
;
da8xx_fb_fix
.
line_length
=
(
lcdc_info
->
width
*
lcd_cfg
->
bpp
)
/
8
;
par
->
lcdc_clk
=
fb_clk
;
par
->
irq
=
platform_get_irq
(
device
,
0
);
if
(
par
->
irq
<
0
)
{
ret
=
-
ENOENT
;
...
...
@@ -814,12 +912,24 @@ static int __init fb_probe(struct platform_device *device)
goto
err_dealloc_cmap
;
}
#ifdef CONFIG_CPU_FREQ
ret
=
lcd_da8xx_cpufreq_register
(
par
);
if
(
ret
)
{
dev_err
(
&
device
->
dev
,
"failed to register cpufreq
\n
"
);
goto
err_cpu_freq
;
}
#endif
/* enable raster engine */
lcdc_write
(
lcdc_read
(
LCD_RASTER_CTRL_REG
)
|
LCD_RASTER_ENABLE
,
LCD_RASTER_CTRL_REG
);
lcd_enable_raster
();
return
0
;
#ifdef CONFIG_CPU_FREQ
err_cpu_freq:
unregister_framebuffer
(
da8xx_fb_info
);
#endif
err_dealloc_cmap:
fb_dealloc_cmap
(
&
da8xx_fb_info
->
cmap
);
...
...
@@ -852,11 +962,35 @@ err_request_mem:
#ifdef CONFIG_PM
static
int
fb_suspend
(
struct
platform_device
*
dev
,
pm_message_t
state
)
{
return
-
EBUSY
;
struct
fb_info
*
info
=
platform_get_drvdata
(
dev
);
struct
da8xx_fb_par
*
par
=
info
->
par
;
acquire_console_sem
();
if
(
par
->
panel_power_ctrl
)
par
->
panel_power_ctrl
(
0
);
fb_set_suspend
(
info
,
1
);
lcd_disable_raster
();
clk_disable
(
par
->
lcdc_clk
);
release_console_sem
();
return
0
;
}
static
int
fb_resume
(
struct
platform_device
*
dev
)
{
return
-
EBUSY
;
struct
fb_info
*
info
=
platform_get_drvdata
(
dev
);
struct
da8xx_fb_par
*
par
=
info
->
par
;
acquire_console_sem
();
if
(
par
->
panel_power_ctrl
)
par
->
panel_power_ctrl
(
1
);
clk_enable
(
par
->
lcdc_clk
);
lcd_enable_raster
();
fb_set_suspend
(
info
,
0
);
release_console_sem
();
return
0
;
}
#else
#define fb_suspend NULL
...
...
include/linux/mtd/partitions.h
View file @
395e9801
...
...
@@ -10,6 +10,7 @@
#define MTD_PARTITIONS_H
#include <linux/types.h>
#include <linux/memory.h>
/*
...
...
@@ -40,6 +41,8 @@ struct mtd_partition {
uint64_t
offset
;
/* offset within the master MTD space */
uint32_t
mask_flags
;
/* master MTD flags to mask out for this partition */
struct
nand_ecclayout
*
ecclayout
;
/* out of band layout for this partition (NAND only)*/
void
(
*
setup
)(
struct
memory_accessor
*
,
void
*
context
);
void
*
context
;
};
#define MTDPART_OFS_NXTBLK (-2)
...
...
include/video/da8xx-fb.h
View file @
395e9801
...
...
@@ -38,6 +38,7 @@ struct da8xx_lcdc_platform_data {
const
char
manu_name
[
10
];
void
*
controller_data
;
const
char
type
[
25
];
void
(
*
panel_power_ctrl
)(
int
);
};
struct
lcd_ctrl_config
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment