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
d78bae00
Commit
d78bae00
authored
Jul 04, 2006
by
Tony Lindgren
Browse files
Options
Browse Files
Download
Plain Diff
Merge source.mvista.com:/home/git/linux-omap-2.6
parents
de7e6976
23b266eb
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
373 additions
and
29 deletions
+373
-29
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/devices.c
+20
-4
drivers/i2c/chips/menelaus.c
drivers/i2c/chips/menelaus.c
+5
-0
drivers/spi/omap2_mcspi.c
drivers/spi/omap2_mcspi.c
+347
-24
include/asm-arm/arch-omap/mcspi.h
include/asm-arm/arch-omap/mcspi.h
+0
-1
include/asm-arm/arch-omap/menelaus.h
include/asm-arm/arch-omap/menelaus.h
+1
-0
No files found.
arch/arm/mach-omap2/devices.c
View file @
d78bae00
...
@@ -112,29 +112,45 @@ static inline void omap_init_sti(void) {}
...
@@ -112,29 +112,45 @@ static inline void omap_init_sti(void) {}
#define OMAP2_MCSPI1_BASE 0x48098000
#define OMAP2_MCSPI1_BASE 0x48098000
#define OMAP2_MCSPI2_BASE 0x4809a000
#define OMAP2_MCSPI2_BASE 0x4809a000
/* FIXME: use resources instead */
static
struct
omap2_mcspi_platform_config
omap2_mcspi1_config
=
{
static
struct
omap2_mcspi_platform_config
omap2_mcspi1_config
=
{
.
base
=
io_p2v
(
OMAP2_MCSPI1_BASE
),
.
num_cs
=
4
,
.
num_cs
=
4
,
};
};
static
struct
resource
omap2_mcspi1_resources
[]
=
{
{
.
start
=
OMAP2_MCSPI1_BASE
,
.
end
=
OMAP2_MCSPI1_BASE
+
0xff
,
.
flags
=
IORESOURCE_MEM
,
},
};
struct
platform_device
omap2_mcspi1
=
{
struct
platform_device
omap2_mcspi1
=
{
.
name
=
"omap2_mcspi"
,
.
name
=
"omap2_mcspi"
,
.
id
=
1
,
.
id
=
1
,
.
num_resources
=
ARRAY_SIZE
(
omap2_mcspi1_resources
),
.
resource
=
omap2_mcspi1_resources
,
.
dev
=
{
.
dev
=
{
.
platform_data
=
&
omap2_mcspi1_config
,
.
platform_data
=
&
omap2_mcspi1_config
,
},
},
};
};
static
struct
omap2_mcspi_platform_config
omap2_mcspi2_config
=
{
static
struct
omap2_mcspi_platform_config
omap2_mcspi2_config
=
{
.
base
=
io_p2v
(
OMAP2_MCSPI2_BASE
),
.
num_cs
=
2
,
.
num_cs
=
2
,
};
};
static
struct
resource
omap2_mcspi2_resources
[]
=
{
{
.
start
=
OMAP2_MCSPI2_BASE
,
.
end
=
OMAP2_MCSPI2_BASE
+
0xff
,
.
flags
=
IORESOURCE_MEM
,
},
};
struct
platform_device
omap2_mcspi2
=
{
struct
platform_device
omap2_mcspi2
=
{
.
name
=
"omap2_mcspi"
,
.
name
=
"omap2_mcspi"
,
.
id
=
2
,
.
id
=
2
,
.
num_resources
=
ARRAY_SIZE
(
omap2_mcspi2_resources
),
.
resource
=
omap2_mcspi2_resources
,
.
dev
=
{
.
dev
=
{
.
platform_data
=
&
omap2_mcspi2_config
,
.
platform_data
=
&
omap2_mcspi2_config
,
},
},
...
...
drivers/i2c/chips/menelaus.c
View file @
d78bae00
...
@@ -594,6 +594,11 @@ int menelaus_set_vmmc(unsigned int mV)
...
@@ -594,6 +594,11 @@ int menelaus_set_vmmc(unsigned int mV)
}
}
EXPORT_SYMBOL
(
menelaus_set_vmmc
);
EXPORT_SYMBOL
(
menelaus_set_vmmc
);
int
menelaus_get_slot_pin_states
(
void
)
{
return
menelaus_read_reg
(
MENELAUS_MCT_PIN_ST
);
}
EXPORT_SYMBOL
(
menelaus_get_slot_pin_states
);
/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
...
...
drivers/spi/omap2_mcspi.c
View file @
d78bae00
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/clk.h>
...
@@ -34,6 +35,7 @@
...
@@ -34,6 +35,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/arch/dma.h>
#include <asm/arch/mcspi.h>
#include <asm/arch/mcspi.h>
#define OMAP2_MCSPI_MAX_FREQ 48000000
#define OMAP2_MCSPI_MAX_FREQ 48000000
...
@@ -68,6 +70,8 @@
...
@@ -68,6 +70,8 @@
#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY (0x01 << 12)
#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY (0x01 << 12)
#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY (0x02 << 12)
#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY (0x02 << 12)
#define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12)
#define OMAP2_MCSPI_CHCONF_TRM_MASK (0x03 << 12)
#define OMAP2_MCSPI_CHCONF_DMAW (1 << 14)
#define OMAP2_MCSPI_CHCONF_DMAR (1 << 15)
#define OMAP2_MCSPI_CHCONF_DPE0 (1 << 16)
#define OMAP2_MCSPI_CHCONF_DPE0 (1 << 16)
#define OMAP2_MCSPI_CHCONF_DPE1 (1 << 17)
#define OMAP2_MCSPI_CHCONF_DPE1 (1 << 17)
#define OMAP2_MCSPI_CHCONF_IS (1 << 18)
#define OMAP2_MCSPI_CHCONF_IS (1 << 18)
...
@@ -81,13 +85,29 @@
...
@@ -81,13 +85,29 @@
#define OMAP2_MCSPI_CHCTRL_EN (1 << 0)
#define OMAP2_MCSPI_CHCTRL_EN (1 << 0)
/* We have 2 DMA channels per CS, one for RX and one for TX */
struct
omap2_mcspi_dma
{
int
dma_tx_channel
;
int
dma_rx_channel
;
int
dma_tx_sync_dev
;
int
dma_rx_sync_dev
;
struct
completion
dma_tx_completion
;
struct
completion
dma_rx_completion
;
};
struct
omap2_mcspi
{
struct
omap2_mcspi
{
struct
tasklet_struct
tasklet
;
struct
work_struct
work
;
spinlock_t
lock
;
spinlock_t
lock
;
struct
list_head
msg_queue
;
struct
list_head
msg_queue
;
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
clk
*
ick
;
struct
clk
*
ick
;
struct
clk
*
fck
;
struct
clk
*
fck
;
/* Virtual base address of the controller */
unsigned
long
base
;
/* SPI1 has 4 channels, while SPI2 has 2 */
struct
omap2_mcspi_dma
*
dma_channels
;
};
};
struct
omap2_mcspi_cs
{
struct
omap2_mcspi_cs
{
...
@@ -95,6 +115,8 @@ struct omap2_mcspi_cs {
...
@@ -95,6 +115,8 @@ struct omap2_mcspi_cs {
int
word_len
;
int
word_len
;
};
};
static
struct
workqueue_struct
*
omap2_mcspi_wq
;
#define MOD_REG_BIT(val, mask, set) do { \
#define MOD_REG_BIT(val, mask, set) do { \
if (set) \
if (set) \
val |= mask; \
val |= mask; \
...
@@ -102,39 +124,52 @@ struct omap2_mcspi_cs {
...
@@ -102,39 +124,52 @@ struct omap2_mcspi_cs {
val &= ~mask; \
val &= ~mask; \
} while(0)
} while(0)
static
inline
void
mcspi_write_reg
(
struct
spi_master
*
master
,
#define MASTER_PDATA(master) (struct omap2_mcspi_platform_config *)((master)->cdev.dev->platform_data)
static
inline
void
mcspi_write_reg
(
const
struct
spi_master
*
master
,
int
idx
,
u32
val
)
int
idx
,
u32
val
)
{
{
struct
omap2_mcspi
_platform_config
*
pdata
=
MASTER_PDATA
(
master
);
struct
omap2_mcspi
*
mcspi
=
class_get_devdata
(
&
master
->
cdev
);
__raw_writel
(
val
,
pdata
->
base
+
idx
);
__raw_writel
(
val
,
mcspi
->
base
+
idx
);
}
}
static
inline
u32
mcspi_read_reg
(
const
struct
spi_master
*
master
,
static
inline
u32
mcspi_read_reg
(
struct
spi_master
*
master
,
int
idx
)
int
idx
)
{
{
struct
omap2_mcspi
_platform_config
*
pdata
=
MASTER_PDATA
(
master
);
struct
omap2_mcspi
*
mcspi
=
class_get_devdata
(
&
master
->
cdev
);
return
__raw_readl
(
pdata
->
base
+
idx
);
return
__raw_readl
(
mcspi
->
base
+
idx
);
}
}
static
inline
void
mcspi_write_cs_reg
(
const
struct
spi_device
*
spi
,
static
inline
void
mcspi_write_cs_reg
(
const
struct
spi_device
*
spi
,
int
idx
,
u32
val
)
int
idx
,
u32
val
)
{
{
struct
omap2_mcspi
_platform_config
*
pdata
=
MASTER_PDATA
(
spi
->
master
);
struct
omap2_mcspi
*
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
__raw_writel
(
val
,
pdata
->
base
+
spi
->
chip_select
*
0x14
+
idx
);
__raw_writel
(
val
,
mcspi
->
base
+
spi
->
chip_select
*
0x14
+
idx
);
}
}
static
inline
u32
mcspi_read_cs_reg
(
const
struct
spi_device
*
spi
,
static
inline
u32
mcspi_read_cs_reg
(
const
struct
spi_device
*
spi
,
int
idx
)
int
idx
)
{
{
struct
omap2_mcspi_platform_config
*
pdata
=
MASTER_PDATA
(
spi
->
master
);
struct
omap2_mcspi
*
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
return
__raw_readl
(
mcspi
->
base
+
spi
->
chip_select
*
0x14
+
idx
);
}
static
void
omap2_mcspi_set_dma_req
(
const
struct
spi_device
*
spi
,
int
is_read
,
int
enable
)
{
u32
l
,
rw
;
l
=
mcspi_read_cs_reg
(
spi
,
OMAP2_MCSPI_CHCONF0
);
if
(
is_read
)
/* 1 is read, 0 write */
rw
=
OMAP2_MCSPI_CHCONF_DMAR
;
else
rw
=
OMAP2_MCSPI_CHCONF_DMAW
;
return
__raw_readl
(
pdata
->
base
+
spi
->
chip_select
*
0x14
+
idx
);
MOD_REG_BIT
(
l
,
rw
,
enable
);
mcspi_write_cs_reg
(
spi
,
OMAP2_MCSPI_CHCONF0
,
l
);
}
}
static
void
omap2_mcspi_set_enable
(
const
struct
spi_device
*
spi
,
int
enable
)
static
void
omap2_mcspi_set_enable
(
const
struct
spi_device
*
spi
,
int
enable
)
...
@@ -167,14 +202,141 @@ static void omap2_mcspi_set_master_mode(struct spi_device *spi, int single_chann
...
@@ -167,14 +202,141 @@ static void omap2_mcspi_set_master_mode(struct spi_device *spi, int single_chann
mcspi_write_reg
(
spi
->
master
,
OMAP2_MCSPI_MODULCTRL
,
l
);
mcspi_write_reg
(
spi
->
master
,
OMAP2_MCSPI_MODULCTRL
,
l
);
}
}
static
void
omap2_mcspi_txrx
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
xfer
)
static
void
omap2_mcspi_txrx_dma
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
xfer
)
{
{
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_cs
*
cs
=
spi
->
controller_state
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
unsigned
int
count
,
c
;
unsigned
long
base
,
tx_reg
,
rx_reg
;
int
word_len
,
data_type
,
element_count
;
u8
*
rx
;
const
u8
*
tx
;
u32
l
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
mcspi_dma
=
&
mcspi
->
dma_channels
[
spi
->
chip_select
];
count
=
xfer
->
len
;
c
=
count
;
word_len
=
cs
->
word_len
;
l
=
mcspi_read_cs_reg
(
spi
,
OMAP2_MCSPI_CHCONF0
);
l
&=
~
OMAP2_MCSPI_CHCONF_TRM_MASK
;
if
(
xfer
->
tx_buf
==
NULL
)
l
|=
OMAP2_MCSPI_CHCONF_TRM_RX_ONLY
;
else
if
(
xfer
->
rx_buf
==
NULL
)
l
|=
OMAP2_MCSPI_CHCONF_TRM_TX_ONLY
;
mcspi_write_cs_reg
(
spi
,
OMAP2_MCSPI_CHCONF0
,
l
);
omap2_mcspi_set_enable
(
spi
,
1
);
base
=
io_v2p
(
mcspi
->
base
)
+
spi
->
chip_select
*
0x14
;
tx_reg
=
base
+
OMAP2_MCSPI_TX0
;
rx_reg
=
base
+
OMAP2_MCSPI_RX0
;
rx
=
xfer
->
rx_buf
;
tx
=
xfer
->
tx_buf
;
if
(
word_len
<=
8
)
{
data_type
=
OMAP_DMA_DATA_TYPE_S8
;
element_count
=
count
;
}
else
if
(
word_len
<=
16
)
{
data_type
=
OMAP_DMA_DATA_TYPE_S16
;
element_count
=
count
>>
1
;
}
else
if
(
word_len
<=
32
)
{
data_type
=
OMAP_DMA_DATA_TYPE_S32
;
element_count
=
count
>>
2
;
}
else
return
;
/* RX_ONLY mode needs dummy data in TX reg */
if
(
tx
==
NULL
)
__raw_writel
(
0
,
mcspi
->
base
+
spi
->
chip_select
*
0x14
+
OMAP2_MCSPI_TX0
);
if
(
tx
!=
NULL
)
{
xfer
->
tx_dma
=
dma_map_single
(
&
spi
->
dev
,
(
void
*
)
tx
,
count
,
DMA_TO_DEVICE
);
if
(
dma_mapping_error
(
xfer
->
tx_dma
))
{
printk
(
KERN_ERR
"%s(): Couldn't DMA map a %d bytes TX buffer
\n
"
,
__FUNCTION__
,
count
);
return
;
}
omap_set_dma_transfer_params
(
mcspi_dma
->
dma_tx_channel
,
data_type
,
element_count
,
1
,
OMAP_DMA_SYNC_ELEMENT
,
mcspi_dma
->
dma_tx_sync_dev
,
0
);
omap_set_dma_dest_params
(
mcspi_dma
->
dma_tx_channel
,
0
,
OMAP_DMA_AMODE_CONSTANT
,
tx_reg
,
0
,
0
);
omap_set_dma_src_params
(
mcspi_dma
->
dma_tx_channel
,
0
,
OMAP_DMA_AMODE_POST_INC
,
xfer
->
tx_dma
,
0
,
0
);
}
if
(
rx
!=
NULL
)
{
xfer
->
rx_dma
=
dma_map_single
(
&
spi
->
dev
,
rx
,
count
,
DMA_FROM_DEVICE
);
if
(
dma_mapping_error
(
xfer
->
rx_dma
))
{
printk
(
KERN_ERR
"%s(): Couldn't DMA map a %d bytes RX buffer
\n
"
,
__FUNCTION__
,
count
);
if
(
tx
!=
NULL
)
dma_unmap_single
(
NULL
,
xfer
->
tx_dma
,
count
,
DMA_TO_DEVICE
);
return
;
}
omap_set_dma_transfer_params
(
mcspi_dma
->
dma_rx_channel
,
data_type
,
element_count
,
1
,
OMAP_DMA_SYNC_ELEMENT
,
mcspi_dma
->
dma_rx_sync_dev
,
1
);
omap_set_dma_src_params
(
mcspi_dma
->
dma_rx_channel
,
0
,
OMAP_DMA_AMODE_CONSTANT
,
rx_reg
,
0
,
0
);
omap_set_dma_dest_params
(
mcspi_dma
->
dma_rx_channel
,
0
,
OMAP_DMA_AMODE_POST_INC
,
xfer
->
rx_dma
,
0
,
0
);
}
if
(
tx
!=
NULL
)
{
omap_start_dma
(
mcspi_dma
->
dma_tx_channel
);
omap2_mcspi_set_dma_req
(
spi
,
0
,
1
);
}
if
(
rx
!=
NULL
)
{
omap_start_dma
(
mcspi_dma
->
dma_rx_channel
);
omap2_mcspi_set_dma_req
(
spi
,
1
,
1
);
}
if
(
tx
!=
NULL
)
{
wait_for_completion
(
&
mcspi_dma
->
dma_tx_completion
);
dma_unmap_single
(
NULL
,
xfer
->
tx_dma
,
count
,
DMA_TO_DEVICE
);
}
if
(
rx
!=
NULL
)
{
wait_for_completion
(
&
mcspi_dma
->
dma_rx_completion
);
dma_unmap_single
(
NULL
,
xfer
->
rx_dma
,
count
,
DMA_FROM_DEVICE
);
}
omap2_mcspi_set_enable
(
spi
,
0
);
}
static
void
omap2_mcspi_txrx_pio
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
xfer
)
{
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_cs
*
cs
=
spi
->
controller_state
;
struct
omap2_mcspi_cs
*
cs
=
spi
->
controller_state
;
unsigned
int
count
,
c
;
unsigned
int
count
,
c
;
u32
l
;
u32
l
;
unsigned
long
base
,
tx_reg
,
rx_reg
,
chstat_reg
;
unsigned
long
base
,
tx_reg
,
rx_reg
,
chstat_reg
;
int
word_len
;
int
word_len
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
count
=
xfer
->
len
;
count
=
xfer
->
len
;
c
=
count
;
c
=
count
;
word_len
=
cs
->
word_len
;
word_len
=
cs
->
word_len
;
...
@@ -191,7 +353,7 @@ static void omap2_mcspi_txrx(struct spi_device *spi, struct spi_transfer *xfer)
...
@@ -191,7 +353,7 @@ static void omap2_mcspi_txrx(struct spi_device *spi, struct spi_transfer *xfer)
/* We store the pre-calculated register addresses on stack to speed
/* We store the pre-calculated register addresses on stack to speed
* up the transfer loop. */
* up the transfer loop. */
base
=
(
MASTER_PDATA
(
spi
->
master
))
->
base
+
spi
->
chip_select
*
0x14
;
base
=
mcspi
->
base
+
spi
->
chip_select
*
0x14
;
tx_reg
=
base
+
OMAP2_MCSPI_TX0
;
tx_reg
=
base
+
OMAP2_MCSPI_TX0
;
rx_reg
=
base
+
OMAP2_MCSPI_RX0
;
rx_reg
=
base
+
OMAP2_MCSPI_RX0
;
chstat_reg
=
base
+
OMAP2_MCSPI_CHSTAT0
;
chstat_reg
=
base
+
OMAP2_MCSPI_CHSTAT0
;
...
@@ -357,28 +519,157 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
...
@@ -357,28 +519,157 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
return
0
;
return
0
;
}
}
static
void
omap2_mcspi_dma_rx_callback
(
int
lch
,
u16
ch_status
,
void
*
data
)
{
struct
spi_device
*
spi
=
(
struct
spi_device
*
)
data
;
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
mcspi_dma
=
&
(
mcspi
->
dma_channels
[
spi
->
chip_select
]);
complete
(
&
mcspi_dma
->
dma_rx_completion
);
/* We must disable the DMA RX request */
omap2_mcspi_set_dma_req
(
spi
,
1
,
0
);
}
static
void
omap2_mcspi_dma_tx_callback
(
int
lch
,
u16
ch_status
,
void
*
data
)
{
struct
spi_device
*
spi
=
(
struct
spi_device
*
)
data
;
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
mcspi_dma
=
&
(
mcspi
->
dma_channels
[
spi
->
chip_select
]);
complete
(
&
mcspi_dma
->
dma_tx_completion
);
/* We must disable the DMA TX request */
omap2_mcspi_set_dma_req
(
spi
,
0
,
0
);
}
static
int
omap2_mcspi_request_dma
(
struct
spi_device
*
spi
)
{
int
rx_dev_id
,
tx_dev_id
;
struct
spi_master
*
master
=
spi
->
master
;
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
mcspi
=
class_get_devdata
(
&
master
->
cdev
);
mcspi_dma
=
&
(
mcspi
->
dma_channels
[
spi
->
chip_select
]);
if
(
master
->
bus_num
==
1
)
{
switch
(
spi
->
chip_select
)
{
case
0
:
rx_dev_id
=
OMAP24XX_DMA_SPI1_RX0
;
tx_dev_id
=
OMAP24XX_DMA_SPI1_TX0
;
break
;
case
1
:
rx_dev_id
=
OMAP24XX_DMA_SPI1_RX1
;
tx_dev_id
=
OMAP24XX_DMA_SPI1_TX1
;
break
;
case
2
:
rx_dev_id
=
OMAP24XX_DMA_SPI1_RX2
;
tx_dev_id
=
OMAP24XX_DMA_SPI1_TX2
;
break
;
case
3
:
rx_dev_id
=
OMAP24XX_DMA_SPI1_RX3
;
tx_dev_id
=
OMAP24XX_DMA_SPI1_TX3
;
break
;
default:
return
-
EINVAL
;
}
}
else
if
(
master
->
bus_num
==
2
)
{
/* McSPI 2 has 1 chipselect */
switch
(
spi
->
chip_select
)
{
case
0
:
rx_dev_id
=
OMAP24XX_DMA_SPI2_RX0
;
tx_dev_id
=
OMAP24XX_DMA_SPI2_TX0
;
break
;
case
1
:
rx_dev_id
=
OMAP24XX_DMA_SPI2_RX1
;
tx_dev_id
=
OMAP24XX_DMA_SPI2_TX1
;
break
;
default:
return
-
EINVAL
;
}
}
else
return
-
EINVAL
;
if
(
omap_request_dma
(
rx_dev_id
,
"McSPI RX"
,
omap2_mcspi_dma_rx_callback
,
spi
,
&
mcspi_dma
->
dma_rx_channel
))
{
printk
(
KERN_ERR
"Unable to request DMA channel for McSPI RX
\n
"
);
return
-
EAGAIN
;
}
if
(
omap_request_dma
(
tx_dev_id
,
"McSPI TX"
,
omap2_mcspi_dma_tx_callback
,
spi
,
&
mcspi_dma
->
dma_tx_channel
))
{
omap_free_dma
(
mcspi_dma
->
dma_rx_channel
);
mcspi_dma
->
dma_rx_channel
=
-
1
;
printk
(
KERN_ERR
"Unable to request DMA channel for McSPI TX
\n
"
);
return
-
EAGAIN
;
}
mcspi_dma
->
dma_rx_sync_dev
=
rx_dev_id
;
mcspi_dma
->
dma_tx_sync_dev
=
tx_dev_id
;
init_completion
(
&
mcspi_dma
->
dma_rx_completion
);
init_completion
(
&
mcspi_dma
->
dma_tx_completion
);
return
0
;
}
static
int
omap2_mcspi_setup
(
struct
spi_device
*
spi
)
static
int
omap2_mcspi_setup
(
struct
spi_device
*
spi
)
{
{
int
ret
;
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
struct
omap2_mcspi_cs
*
cs
=
spi
->
controller_state
;
struct
omap2_mcspi_cs
*
cs
=
spi
->
controller_state
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
mcspi_dma
=
&
mcspi
->
dma_channels
[
spi
->
chip_select
];
if
(
!
cs
)
{
if
(
!
cs
)
{
cs
=
kzalloc
(
sizeof
*
cs
,
SLAB_KERNEL
);
cs
=
kzalloc
(
sizeof
*
cs
,
SLAB_KERNEL
);
if
(
!
cs
)
if
(
!
cs
)
return
-
ENOMEM
;
return
-
ENOMEM
;
spi
->
controller_state
=
cs
;
spi
->
controller_state
=
cs
;
}
}
if
(
mcspi_dma
->
dma_rx_channel
==
-
1
||
mcspi_dma
->
dma_tx_channel
==
-
1
)
{
ret
=
omap2_mcspi_request_dma
(
spi
);
if
(
ret
<
0
)
return
ret
;
}
return
omap2_mcspi_setup_transfer
(
spi
,
NULL
);
return
omap2_mcspi_setup_transfer
(
spi
,
NULL
);
}
}
static
void
omap2_mcspi_cleanup
(
const
struct
spi_device
*
spi
)
static
void
omap2_mcspi_cleanup
(
const
struct
spi_device
*
spi
)
{
{
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi_dma
*
mcspi_dma
;
mcspi
=
class_get_devdata
(
&
spi
->
master
->
cdev
);
mcspi_dma
=
&
mcspi
->
dma_channels
[
spi
->
chip_select
];
if
(
spi
->
controller_state
!=
NULL
)
if
(
spi
->
controller_state
!=
NULL
)
kfree
(
spi
->
controller_state
);
kfree
(
spi
->
controller_state
);
if
(
mcspi_dma
->
dma_rx_channel
!=
-
1
&&
mcspi_dma
->
dma_tx_channel
!=
-
1
)
{
omap_free_dma
(
mcspi_dma
->
dma_tx_channel
);
omap_free_dma
(
mcspi_dma
->
dma_rx_channel
);
}
}
}
static
void
omap2_mcspi_work
(
unsigned
long
arg
)
static
void
omap2_mcspi_work
(
void
*
arg
)
{
{
struct
omap2_mcspi
*
mcspi
=
(
struct
omap2_mcspi
*
)
arg
;
struct
omap2_mcspi
*
mcspi
=
(
struct
omap2_mcspi
*
)
arg
;
unsigned
long
flags
;
unsigned
long
flags
;
...
@@ -423,7 +714,11 @@ static void omap2_mcspi_work(unsigned long arg)
...
@@ -423,7 +714,11 @@ static void omap2_mcspi_work(unsigned long arg)
cs_active
=
1
;
cs_active
=
1
;
}
}
omap2_mcspi_txrx
(
spi
,
t
);
if
(
m
->
is_dma_mapped
&&
(
t
->
tx_dma
!=
0
||
t
->
rx_dma
!=
0
))
omap2_mcspi_txrx_dma
(
spi
,
t
);
else
omap2_mcspi_txrx_pio
(
spi
,
t
);
if
(
t
->
cs_change
)
{
if
(
t
->
cs_change
)
{
/* In the last transfer entry the flag means
/* In the last transfer entry the flag means
...
@@ -465,7 +760,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
...
@@ -465,7 +760,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m)
list_add_tail
(
&
m
->
queue
,
&
mcspi
->
msg_queue
);
list_add_tail
(
&
m
->
queue
,
&
mcspi
->
msg_queue
);
spin_unlock_irqrestore
(
&
mcspi
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
mcspi
->
lock
,
flags
);
tasklet_hi_schedule
(
&
mcspi
->
tasklet
);
queue_work
(
omap2_mcspi_wq
,
&
mcspi
->
work
);
return
0
;
return
0
;
}
}
...
@@ -486,8 +781,9 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
...
@@ -486,8 +781,9 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
omap2_mcspi_platform_config
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
omap2_mcspi_platform_config
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
omap2_mcspi
*
mcspi
;
struct
omap2_mcspi
*
mcspi
;
int
status
=
0
;
struct
resource
*
r
;
int
status
=
0
,
i
;
if
(
!
pdata
)
if
(
!
pdata
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -516,7 +812,15 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
...
@@ -516,7 +812,15 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
mcspi
=
class_get_devdata
(
&
master
->
cdev
);
mcspi
=
class_get_devdata
(
&
master
->
cdev
);
mcspi
->
master
=
master
;
mcspi
->
master
=
master
;
tasklet_init
(
&
mcspi
->
tasklet
,
omap2_mcspi_work
,
(
unsigned
long
)
mcspi
);
r
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
r
==
NULL
)
{
status
=
-
ENODEV
;
goto
err1
;
}
mcspi
->
base
=
io_p2v
(
r
->
start
);
INIT_WORK
(
&
mcspi
->
work
,
omap2_mcspi_work
,
mcspi
);
spin_lock_init
(
&
mcspi
->
lock
);
spin_lock_init
(
&
mcspi
->
lock
);
INIT_LIST_HEAD
(
&
mcspi
->
msg_queue
);
INIT_LIST_HEAD
(
&
mcspi
->
msg_queue
);
...
@@ -536,15 +840,30 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
...
@@ -536,15 +840,30 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev)
}
}
clk_enable
(
mcspi
->
fck
);
clk_enable
(
mcspi
->
fck
);
mcspi
->
dma_channels
=
(
struct
omap2_mcspi_dma
*
)
kzalloc
(
master
->
num_chipselect
*
sizeof
(
struct
omap2_mcspi_dma
),
GFP_KERNEL
);
if
(
mcspi
->
dma_channels
==
NULL
)
goto
err3
;
for
(
i
=
0
;
i
<
master
->
num_chipselect
;
i
++
)
{
mcspi
->
dma_channels
[
i
].
dma_rx_channel
=
-
1
;
mcspi
->
dma_channels
[
i
].
dma_tx_channel
=
-
1
;
}
if
(
omap2_mcspi_reset
(
master
)
<
0
)
if
(
omap2_mcspi_reset
(
master
)
<
0
)
goto
err
3
;
goto
err
4
;
status
=
spi_register_master
(
master
);
status
=
spi_register_master
(
master
);
if
(
status
<
0
)
if
(
status
<
0
)
goto
err
3
;
goto
err
4
;
return
status
;
return
status
;
err4:
kfree
(
mcspi
->
dma_channels
);
err3:
err3:
clk_disable
(
mcspi
->
fck
);
clk_disable
(
mcspi
->
fck
);
clk_put
(
mcspi
->
fck
);
clk_put
(
mcspi
->
fck
);
...
@@ -571,6 +890,7 @@ static int __devexit omap2_mcspi_remove(struct platform_device *pdev)
...
@@ -571,6 +890,7 @@ static int __devexit omap2_mcspi_remove(struct platform_device *pdev)
clk_disable
(
mcspi
->
ick
);
clk_disable
(
mcspi
->
ick
);
clk_put
(
mcspi
->
ick
);
clk_put
(
mcspi
->
ick
);
class_device_put
(
&
master
->
cdev
);
class_device_put
(
&
master
->
cdev
);
kfree
(
mcspi
->
dma_channels
);
return
0
;
return
0
;
}
}
...
@@ -589,6 +909,9 @@ EXPORT_SYMBOL_GPL(omap2_mcspi_driver);
...
@@ -589,6 +909,9 @@ EXPORT_SYMBOL_GPL(omap2_mcspi_driver);
static
int
__init
omap2_mcspi_init
(
void
)
static
int
__init
omap2_mcspi_init
(
void
)
{
{
printk
(
KERN_INFO
"OMAP24xx McSPI driver initializing
\n
"
);
printk
(
KERN_INFO
"OMAP24xx McSPI driver initializing
\n
"
);
omap2_mcspi_wq
=
create_workqueue
(
"OMAP McSPI"
);
if
(
omap2_mcspi_wq
==
NULL
)
return
-
1
;
return
platform_driver_register
(
&
omap2_mcspi_driver
);
return
platform_driver_register
(
&
omap2_mcspi_driver
);
}
}
subsys_initcall
(
omap2_mcspi_init
);
subsys_initcall
(
omap2_mcspi_init
);
...
...
include/asm-arm/arch-omap/mcspi.h
View file @
d78bae00
...
@@ -2,7 +2,6 @@
...
@@ -2,7 +2,6 @@
#define _OMAP2_MCSPI_H
#define _OMAP2_MCSPI_H
struct
omap2_mcspi_platform_config
{
struct
omap2_mcspi_platform_config
{
unsigned
long
base
;
unsigned
short
num_cs
;
unsigned
short
num_cs
;
};
};
...
...
include/asm-arm/arch-omap/menelaus.h
View file @
d78bae00
...
@@ -18,6 +18,7 @@ extern int menelaus_set_vio(unsigned int mV);
...
@@ -18,6 +18,7 @@ extern int menelaus_set_vio(unsigned int mV);
extern
int
menelaus_set_vmmc
(
unsigned
int
mV
);
extern
int
menelaus_set_vmmc
(
unsigned
int
mV
);
extern
int
menelaus_set_vdcdc
(
int
dcdc
,
unsigned
int
mV
);
extern
int
menelaus_set_vdcdc
(
int
dcdc
,
unsigned
int
mV
);
extern
int
menelaus_set_slot_sel
(
int
enable
);
extern
int
menelaus_set_slot_sel
(
int
enable
);
extern
int
menelaus_get_slot_pin_states
(
void
);
#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
#if defined(CONFIG_ARCH_OMAP24XX) && defined(CONFIG_MENELAUS)
#define omap_has_menelaus() 1
#define omap_has_menelaus() 1
...
...
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