Driver for DVB-T cards with cx23882 chipset, like WinTV NOVA-T PCI
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20678 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
36e0e8a8bd
commit
083a11a3f4
41
src/add-ons/kernel/drivers/dvb/cx23882/config.h
Normal file
41
src/add-ons/kernel/drivers/dvb/cx23882/config.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define BUILD __DATE__ " "__TIME__
|
||||
#define INFO1 "cx23882: DVB-T Driver. Version " VERSION ", Revision " REVISION ", Build " BUILD
|
||||
#define INFO2 "cx23882: Copyright (c) 2004-2006 Marcus Overhagen. All rights reserved.\n"
|
||||
|
||||
#define MAX_CARDS 8
|
||||
|
||||
#define PCI_LATENCY 0x20
|
||||
|
||||
#define I2C_ADDR_DEMOD 0x43
|
||||
#define I2C_ADDR_EEPROM 0x50
|
||||
#define I2C_ADDR_PLL 0x61
|
||||
|
||||
#endif
|
306
src/add-ons/kernel/drivers/dvb/cx23882/cx22702.c
Normal file
306
src/add-ons/kernel/drivers/dvb/cx23882/cx22702.c
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include "cx22702.h"
|
||||
#include "dtt7592.h"
|
||||
#include "config.h"
|
||||
#include "dvb.h"
|
||||
|
||||
#define TRACE_CX22702
|
||||
#ifdef TRACE_CX22702
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
cx22702_reg_dump(i2c_bus *bus)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 256; i++) {
|
||||
uint8 data;
|
||||
if (cx22702_reg_read(bus, i, &data) != B_OK)
|
||||
dprintf("cx22702_reg 0x%02x error\n", i);
|
||||
else
|
||||
dprintf("cx22702_reg 0x%02x value 0x%02x\n", i, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_reg_write(i2c_bus *bus, uint8 reg, uint8 data)
|
||||
{
|
||||
status_t res;
|
||||
uint8 buf[2] = {reg, data};
|
||||
res = i2c_write(bus, I2C_ADDR_DEMOD, buf, 2);
|
||||
if (res != B_OK)
|
||||
TRACE("cx22702_reg_write error, reg 0x%02x, value 0x%02x\n", reg, data);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_reg_read(i2c_bus *bus, uint8 reg, uint8 *data)
|
||||
{
|
||||
status_t res;
|
||||
res = i2c_xfer(bus, I2C_ADDR_DEMOD, ®, 1, data, 1);
|
||||
if (res != B_OK)
|
||||
TRACE("cx22702_reg_read error, reg 0x%02x\n", reg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_init(i2c_bus *bus)
|
||||
{
|
||||
if (cx22702_reg_write(bus, 0x00, 0x02) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK) return B_ERROR;
|
||||
snooze(10000);
|
||||
if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x09, 0x01) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x0B, 0x04) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x0C, 0x00) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x0D, 0x80) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x26, 0x80) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x2D, 0xff) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0xDC, 0x00) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0xE4, 0x00) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0xF8, 0x02) != B_OK) return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x00, 0x01) != B_OK) return B_ERROR;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_frequency_info(i2c_bus *bus, dvb_frequency_info_t *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->frequency_min = 149000000;
|
||||
info->frequency_max = 860000000;
|
||||
info->frequency_step = 166667;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_set_tuning_parameters(i2c_bus *bus, const dvb_t_tuning_parameters_t *params)
|
||||
{
|
||||
uint8 data;
|
||||
status_t res;
|
||||
|
||||
if (cx22702_reg_write(bus, 0x00, 0x00) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
res = dtt7592_set_frequency(bus, params->frequency, params->bandwidth);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
if (cx22702_reg_read(bus, 0x0c, &data) != B_OK)
|
||||
return B_ERROR;
|
||||
switch (params->inversion) {
|
||||
case DVB_INVERSION_ON: data |= 0x01; break;
|
||||
case DVB_INVERSION_OFF: data &= ~0x01; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
switch (params->bandwidth) {
|
||||
case DVB_BANDWIDTH_6_MHZ: data = (data & ~0x10) | 0x20; break;
|
||||
case DVB_BANDWIDTH_7_MHZ: data = (data & ~0x20) | 0x10; break;
|
||||
case DVB_BANDWIDTH_8_MHZ: data &= ~0x30; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
if (cx22702_reg_write(bus, 0x0c, data) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
switch (params->modulation) {
|
||||
case DVB_MODULATION_QPSK: data = 0x00; break;
|
||||
case DVB_MODULATION_16_QAM: data = 0x08; break;
|
||||
case DVB_MODULATION_64_QAM: data = 0x10; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
switch (params->hierarchy) {
|
||||
case DVB_HIERARCHY_NONE: break;
|
||||
case DVB_HIERARCHY_1: data |= 0x01; break;
|
||||
case DVB_HIERARCHY_2: data |= 0x02; break;
|
||||
case DVB_HIERARCHY_4: data |= 0x03; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
if (cx22702_reg_write(bus, 0x06, data) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
switch (params->code_rate_hp) {
|
||||
case DVB_FEC_NONE: data = 0x00; break;
|
||||
case DVB_FEC_1_2: data = 0x00; break;
|
||||
case DVB_FEC_2_3: data = 0x08; break;
|
||||
case DVB_FEC_3_4: data = 0x10; break;
|
||||
case DVB_FEC_5_6: data = 0x18; break;
|
||||
case DVB_FEC_6_7: data = 0x20; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
switch (params->code_rate_lp) {
|
||||
case DVB_FEC_NONE: break;
|
||||
case DVB_FEC_1_2: break;
|
||||
case DVB_FEC_2_3: data |= 0x01; break;
|
||||
case DVB_FEC_3_4: data |= 0x02; break;
|
||||
case DVB_FEC_5_6: data |= 0x03; break;
|
||||
case DVB_FEC_6_7: data |= 0x04; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
if (cx22702_reg_write(bus, 0x07, data) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
switch (params->transmission_mode) {
|
||||
case DVB_TRANSMISSION_MODE_2K: data = 0x00; break;
|
||||
case DVB_TRANSMISSION_MODE_8K: data = 0x01; break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
switch (params->guard_interval) {
|
||||
case DVB_GUARD_INTERVAL_1_4: data |= 0x0c; break;
|
||||
case DVB_GUARD_INTERVAL_1_8: data |= 0x08; break;
|
||||
case DVB_GUARD_INTERVAL_1_16: data |= 0x04; break;
|
||||
case DVB_GUARD_INTERVAL_1_32: break;
|
||||
default: return B_ERROR;
|
||||
}
|
||||
if (cx22702_reg_write(bus, 0x08, data) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (cx22702_reg_read(bus, 0x0b, &data) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0x0b, data | 0x02) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (cx22702_reg_write(bus, 0x00, 0x01) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
// cx22702_reg_dump(bus);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_tuning_parameters(i2c_bus *bus, dvb_t_tuning_parameters_t *params)
|
||||
{
|
||||
uint8 reg01, reg02, reg03, reg0A, reg0C;
|
||||
|
||||
if (cx22702_reg_read(bus, 0x01, ®01) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0x02, ®02) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0x03, ®03) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0x0a, ®0A) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0x0c, ®0C) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
memset(params, 0, sizeof(*params));
|
||||
params->inversion = (reg0C & 0x01) ? DVB_INVERSION_ON : DVB_INVERSION_OFF;
|
||||
|
||||
// XXX TODO...
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_status(i2c_bus *bus, dvb_status_t *status)
|
||||
{
|
||||
uint8 reg0A, reg23;
|
||||
|
||||
if (cx22702_reg_read(bus, 0x0a, ®0A) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0x23, ®23) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
*status = 0;
|
||||
if (reg0A & 0x10)
|
||||
*status |= DVB_STATUS_LOCK | DVB_STATUS_VITERBI | DVB_STATUS_SYNC;
|
||||
if (reg0A & 0x20)
|
||||
*status |= DVB_STATUS_CARRIER;
|
||||
if (reg23 < 0xf0)
|
||||
*status |= DVB_STATUS_SIGNAL;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_ss(i2c_bus *bus, uint32 *ss)
|
||||
{
|
||||
uint8 reg23;
|
||||
if (cx22702_reg_read(bus, 0x23, ®23) != B_OK)
|
||||
return B_ERROR;
|
||||
*ss = reg23;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_ber(i2c_bus *bus, uint32 *ber)
|
||||
{
|
||||
uint8 regDE_1, regDE_2, regDF;
|
||||
int trys;
|
||||
|
||||
trys = 50;
|
||||
do {
|
||||
if (cx22702_reg_read(bus, 0xDE, ®DE_1) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0xDF, ®DF) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_read(bus, 0xDE, ®DE_2) != B_OK)
|
||||
return B_ERROR;
|
||||
} while (regDE_1 != regDE_2 && --trys > 0);
|
||||
if (trys == 0)
|
||||
return B_ERROR;
|
||||
|
||||
*ber = (regDE_1 & 0x7f) << 7 | (regDF & 0x7f);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_snr(i2c_bus *bus, uint32 *snr)
|
||||
{
|
||||
uint32 ber;
|
||||
status_t stat = cx22702_get_ber(bus, &ber);
|
||||
*snr = 16384 - ber;
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx22702_get_upc(i2c_bus *bus, uint32 *upc)
|
||||
{
|
||||
uint8 regE3;
|
||||
|
||||
if (cx22702_reg_read(bus, 0xE3, ®E3) != B_OK)
|
||||
return B_ERROR;
|
||||
if (cx22702_reg_write(bus, 0xE3, 0) != B_OK)
|
||||
return B_ERROR;
|
||||
*upc = regE3;
|
||||
return B_OK;
|
||||
}
|
47
src/add-ons/kernel/drivers/dvb/cx23882/cx22702.h
Normal file
47
src/add-ons/kernel/drivers/dvb/cx23882/cx22702.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __CX22702_H
|
||||
#define __CX22702_H
|
||||
|
||||
#include "i2c-core.h"
|
||||
#include "dvb.h"
|
||||
|
||||
status_t cx22702_reg_write(i2c_bus *bus, uint8 reg, uint8 data);
|
||||
status_t cx22702_reg_read(i2c_bus *bus, uint8 reg, uint8 *data);
|
||||
|
||||
status_t cx22702_init(i2c_bus *bus);
|
||||
|
||||
status_t cx22702_get_frequency_info(i2c_bus *bus, dvb_frequency_info_t *info);
|
||||
|
||||
status_t cx22702_set_tuning_parameters(i2c_bus *bus, const dvb_t_tuning_parameters_t *params);
|
||||
status_t cx22702_get_tuning_parameters(i2c_bus *bus, dvb_t_tuning_parameters_t *params);
|
||||
|
||||
status_t cx22702_get_status(i2c_bus *bus, dvb_status_t *status);
|
||||
status_t cx22702_get_ss(i2c_bus *bus, uint32 *ss);
|
||||
status_t cx22702_get_ber(i2c_bus *bus, uint32 *ber);
|
||||
status_t cx22702_get_snr(i2c_bus *bus, uint32 *snr);
|
||||
status_t cx22702_get_upc(i2c_bus *bus, uint32 *upc);
|
||||
|
||||
#endif
|
377
src/add-ons/kernel/drivers/dvb/cx23882/cx23882.c
Normal file
377
src/add-ons/kernel/drivers/dvb/cx23882/cx23882.c
Normal file
@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "cx23882.h"
|
||||
#include "util.h"
|
||||
#include <KernelExport.h>
|
||||
#include <ByteOrder.h>
|
||||
#include <Drivers.h>
|
||||
|
||||
|
||||
#define TRACE_CX23882
|
||||
#ifdef TRACE_CX23882
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
// settings for hardware stream sync
|
||||
#define MPEG2_SYNC_BYTE 0x47
|
||||
#define MPEG2_PACKET_SIZE 188
|
||||
#define SYNC_PACKET_COUNT 7 // 0 and 5 don't seem to work
|
||||
|
||||
// Line size is also used as FIFO size!
|
||||
// BYTES_PER_LINE must be a multiple of 8 and <= 4096 bytes
|
||||
#define PACKETS_PER_LINE 20
|
||||
#define BYTES_PER_LINE (PACKETS_PER_LINE * MPEG2_PACKET_SIZE)
|
||||
|
||||
#define SRAM_START_ADDRESS 0x180000
|
||||
#define SRAM_BASE_CMDS_TS 0x200
|
||||
#define SRAM_BASE_RISC_PROG 0x400
|
||||
#define SRAM_BASE_RISC_QUEUE 0x800
|
||||
#define SRAM_BASE_CDT 0x900
|
||||
#define SRAM_BASE_FIFO_0 0x1000
|
||||
#define SRAM_BASE_FIFO_1 0x2000
|
||||
|
||||
// About 64 kByte DMA buffer size
|
||||
#define LINES_PER_BUFFER 16
|
||||
#define DMA_BUFFER_SIZE (LINES_PER_BUFFER * BYTES_PER_LINE)
|
||||
|
||||
|
||||
static status_t cx23882_buffers_alloc(cx23882_device *device);
|
||||
static void cx23882_buffers_free(cx23882_device *device);
|
||||
static void cx23882_risc_ram_setup(cx23882_device *device);
|
||||
static void cx23882_sram_setup(cx23882_device *device);
|
||||
static void cx23882_via_sis_fixup(cx23882_device *device);
|
||||
|
||||
|
||||
void
|
||||
cx23882_reset(cx23882_device *device)
|
||||
{
|
||||
// software reset (XXX Test)
|
||||
reg_write32(0x38c06c, 1);
|
||||
snooze(200000);
|
||||
|
||||
// disable RISC controller
|
||||
reg_write32(REG_DEV_CNTRL2, 0);
|
||||
|
||||
// disable TS interface DMA
|
||||
reg_write32(REG_TS_DMA_CNTRL, 0x0);
|
||||
|
||||
// disable VIP interface up- & downstram DMA
|
||||
reg_write32(REG_VIP_STREAM_EN, 0x0);
|
||||
|
||||
// disable host interface up- & downstram DMA
|
||||
reg_write32(REG_HST_STREAM_EN, 0x0);
|
||||
|
||||
// stop all interrupts
|
||||
reg_write32(REG_PCI_INT_MSK, 0x0);
|
||||
reg_write32(REG_VID_INT_MSK, 0x0);
|
||||
reg_write32(REG_AUD_INT_MSK, 0x0);
|
||||
reg_write32(REG_TS_INT_MSK, 0x0);
|
||||
reg_write32(REG_VIP_INT_MSK, 0x0);
|
||||
reg_write32(REG_HST_INT_MSK, 0x0);
|
||||
reg_write32(REG_DMA_RISC_INT_MSK, 0x0);
|
||||
|
||||
// clear all pending interrupts
|
||||
reg_write32(REG_PCI_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_VID_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_AUD_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_TS_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_VIP_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_HST_INT_STAT, 0xffffffff);
|
||||
reg_write32(REG_DMA_RISC_INT_MSK, 0xffffffff);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx23882_init(cx23882_device *device)
|
||||
{
|
||||
// assumes that cx23882_reset() has already been called
|
||||
|
||||
status_t err;
|
||||
|
||||
if ((err = cx23882_buffers_alloc(device)) < B_OK) {
|
||||
dprintf("cx23882: Error, buffer alloc failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
device->capture_size = DMA_BUFFER_SIZE;
|
||||
|
||||
cx23882_via_sis_fixup(device);
|
||||
|
||||
// Set FIFO thresholds, should be 0 < x <= 7
|
||||
reg_write32(REG_PDMA_STHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6);
|
||||
reg_write32(REG_PDMA_DTHRSH, PDMA_ISBTHRSH_6 | PDMA_PCITHRSH_6);
|
||||
|
||||
// init risc programm
|
||||
cx23882_risc_ram_setup(device);
|
||||
|
||||
// init sram
|
||||
cx23882_sram_setup(device);
|
||||
|
||||
// Reset counter to 0
|
||||
reg_write32(REG_TS_GP_CNT_CNTRL, 0x3);
|
||||
|
||||
// Line length for RISC DMA
|
||||
reg_write32(REG_TS_LNGTH, BYTES_PER_LINE);
|
||||
|
||||
// Set serial interface mode
|
||||
reg_write32(REG_TS_GEN_CONTROL, reg_read32(REG_TS_GEN_CONTROL) | TS_GEN_CONTROL_IPB_SMODE);
|
||||
|
||||
// Setup hardware MPEG2 fec interface
|
||||
reg_write32(REG_HW_SOP_CONTROL, (MPEG2_SYNC_BYTE << 16) | (MPEG2_PACKET_SIZE << 4) | SYNC_PACKET_COUNT);
|
||||
|
||||
// Setup TSSTOP status, active low, rising and falling edge, single bit width
|
||||
reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) | 0x18000);
|
||||
reg_write32(REG_TS_SOP_STATUS, reg_read32(REG_TS_SOP_STATUS) & ~0x06000);
|
||||
|
||||
// Enable interrupts for MPEG TS and all errors
|
||||
reg_write32(REG_PCI_INT_MSK, reg_read32(REG_PCI_INT_MSK) | PCI_INT_STAT_TS_INT | 0x00fc00);
|
||||
reg_write32(REG_TS_INT_MSK, reg_read32(REG_TS_INT_MSK) | TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2 | 0x1f1100);
|
||||
|
||||
TRACE("cx23882_init done\n");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx23882_terminate(cx23882_device *device)
|
||||
{
|
||||
cx23882_reset(device);
|
||||
|
||||
cx23882_buffers_free(device);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx23882_start_capture(cx23882_device *device)
|
||||
{
|
||||
TRACE("cx23882_start_capture\n");
|
||||
|
||||
// start RISC processor and DMA
|
||||
reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) | DEV_CNTRL2_RUN_RISC);
|
||||
reg_write32(REG_TS_DMA_CNTRL, reg_read32(REG_TS_DMA_CNTRL) | TS_DMA_CNTRL_TS_FIFO_EN | TS_DMA_CNTRL_TS_RISC_EN);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
cx23882_stop_capture(cx23882_device *device)
|
||||
{
|
||||
TRACE("cx23882_stop_capture\n");
|
||||
|
||||
// stop RISC processor and DMA
|
||||
reg_write32(REG_TS_DMA_CNTRL, reg_read32(REG_TS_DMA_CNTRL) & ~(TS_DMA_CNTRL_TS_FIFO_EN | TS_DMA_CNTRL_TS_RISC_EN));
|
||||
reg_write32(REG_DEV_CNTRL2, reg_read32(REG_DEV_CNTRL2) & ~DEV_CNTRL2_RUN_RISC);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
cx23882_mpegts_int(cx23882_device *device)
|
||||
{
|
||||
uint32 mstat = reg_read32(REG_TS_INT_MSTAT);
|
||||
reg_write32(REG_TS_INT_STAT, mstat);
|
||||
|
||||
// dprintf("cx23882_mpegts_int got 0x%08lx\n", mstat);
|
||||
|
||||
if (mstat & TS_INT_STAT_OPC_ERR) {
|
||||
dprintf("cx23882_mpegts_int RISC opcode error\n");
|
||||
reg_write32(REG_PCI_INT_MSK, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mstat & (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) == (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) {
|
||||
dprintf("cx23882_mpegts_int both buffers ready\n");
|
||||
mstat = TS_INT_STAT_TS_RISC1;
|
||||
}
|
||||
|
||||
if (mstat & TS_INT_STAT_TS_RISC1) {
|
||||
int32 count;
|
||||
// dprintf("cx23882_mpegts_int buffer 1 at %Ld\n", system_time());
|
||||
device->capture_data = device->dma_buf1_virt;
|
||||
device->capture_end_time = system_time();
|
||||
get_sem_count(device->capture_sem, &count);
|
||||
if (count <= 0)
|
||||
release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
|
||||
if (mstat & TS_INT_STAT_TS_RISC2) {
|
||||
int32 count;
|
||||
// dprintf("cx23882_mpegts_int buffer 2 at %Ld\n", system_time());
|
||||
device->capture_data = device->dma_buf2_virt;
|
||||
device->capture_end_time = system_time();
|
||||
get_sem_count(device->capture_sem, &count);
|
||||
if (count <= 0)
|
||||
release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
cx23882_int(void *data)
|
||||
{
|
||||
cx23882_device *device = data;
|
||||
uint32 mstat;
|
||||
uint32 wmstat;
|
||||
|
||||
mstat = reg_read32(REG_PCI_INT_MSTAT);
|
||||
if (!mstat)
|
||||
return B_UNHANDLED_INTERRUPT;
|
||||
|
||||
if (mstat & (PCI_INT_STAT_HST_INT | PCI_INT_STAT_VIP_INT | PCI_INT_STAT_AUD_INT | PCI_INT_STAT_VID_INT)) {
|
||||
// serious error, these bits should not be set
|
||||
dprintf("cx23882_int error: msk 0x%08lx, stat 0x%08lx, mstat 0x%08lx\n", reg_read32(REG_PCI_INT_MSK), reg_read32(REG_PCI_INT_STAT), mstat);
|
||||
reg_write32(REG_PCI_INT_MSK, 0);
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
wmstat = mstat & ~(PCI_INT_STAT_HST_INT | PCI_INT_STAT_VIP_INT | PCI_INT_STAT_TS_INT | PCI_INT_STAT_AUD_INT | PCI_INT_STAT_VID_INT);
|
||||
if (wmstat)
|
||||
reg_write32(REG_PCI_INT_STAT, wmstat);
|
||||
|
||||
if (wmstat)
|
||||
dprintf("cx23882_int got 0x%08lx\n", wmstat);
|
||||
|
||||
if (mstat & PCI_INT_STAT_TS_INT) {
|
||||
cx23882_mpegts_int(device);
|
||||
return B_INVOKE_SCHEDULER;
|
||||
} else {
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
cx23882_buffers_alloc(cx23882_device *device)
|
||||
{
|
||||
device->dma_buf1_area = alloc_mem(&device->dma_buf1_virt, &device->dma_buf1_phys, DMA_BUFFER_SIZE, B_READ_AREA, "cx23882 dma buf 1");
|
||||
device->dma_buf2_area = alloc_mem(&device->dma_buf2_virt, &device->dma_buf2_phys, DMA_BUFFER_SIZE, B_READ_AREA, "cx23882 dma buf 2");
|
||||
if (device->dma_buf1_area < B_OK || device->dma_buf2_area < B_OK) {
|
||||
cx23882_buffers_free(device);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cx23882_buffers_free(cx23882_device *device)
|
||||
{
|
||||
if (device->dma_buf1_area >= 0)
|
||||
delete_area(device->dma_buf1_area);
|
||||
if (device->dma_buf2_area >= 0)
|
||||
delete_area(device->dma_buf2_area);
|
||||
device->dma_buf1_area = -1;
|
||||
device->dma_buf2_area = -1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cx23882_sram_setup(cx23882_device *device)
|
||||
{
|
||||
dprintf("cx23882_sram_setup enter\n");
|
||||
|
||||
// setup CDT entries for both FIFOs
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0);
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CDT + 16, SRAM_START_ADDRESS + SRAM_BASE_FIFO_1);
|
||||
|
||||
// setup CDMS
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x00, SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG);
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x04, SRAM_START_ADDRESS + SRAM_BASE_CDT);
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x08, (2 * 16) / 8); // FIFO count = 2
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x0c, SRAM_START_ADDRESS + SRAM_BASE_RISC_QUEUE);
|
||||
reg_write32(SRAM_START_ADDRESS + SRAM_BASE_CMDS_TS + 0x10, 0x80000000 | (0x100 / 4));
|
||||
|
||||
// setup DMA registers
|
||||
reg_write32(REG_DMA28_PTR1, SRAM_START_ADDRESS + SRAM_BASE_FIFO_0);
|
||||
reg_write32(REG_DMA28_PTR2, SRAM_START_ADDRESS + SRAM_BASE_CDT);
|
||||
reg_write32(REG_DMA28_CNT1, BYTES_PER_LINE / 8);
|
||||
reg_write32(REG_DMA28_CNT2, (2 * 16) / 8); // FIFO count = 2
|
||||
|
||||
dprintf("cx23882_sram_setup leave\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cx23882_risc_ram_setup(cx23882_device *device)
|
||||
{
|
||||
char *start = (char *)(device->regs) + SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG;
|
||||
volatile uint32 *rp = (volatile uint32 *)start;
|
||||
int i;
|
||||
|
||||
#define set_opcode(a) (*rp++) = B_HOST_TO_LENDIAN_INT32((a))
|
||||
|
||||
dprintf("cx23882_risc_ram_setup enter\n");
|
||||
|
||||
// sync
|
||||
set_opcode(RISC_RESYNC | 0);
|
||||
|
||||
// copy buffer 1
|
||||
for (i = 0; i < LINES_PER_BUFFER; i++) {
|
||||
set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE);
|
||||
set_opcode((unsigned long)device->dma_buf1_phys + i * BYTES_PER_LINE);
|
||||
}
|
||||
|
||||
// execute IRQ 1
|
||||
set_opcode(RISC_SKIP | RISC_IRQ1 | RISC_SOL | 0);
|
||||
|
||||
// copy buffer 2
|
||||
for (i = 0; i < LINES_PER_BUFFER; i++) {
|
||||
set_opcode(RISC_WRITE | RISC_SOL | RISC_EOL | BYTES_PER_LINE);
|
||||
set_opcode((unsigned long)device->dma_buf2_phys + i * BYTES_PER_LINE);
|
||||
}
|
||||
|
||||
// execute IRQ 2
|
||||
set_opcode(RISC_SKIP | RISC_IRQ2 | RISC_SOL | 0);
|
||||
|
||||
// jmp to start, but skip sync instruction
|
||||
set_opcode(RISC_JUMP | RISC_SRP);
|
||||
set_opcode(SRAM_START_ADDRESS + SRAM_BASE_RISC_PROG + 4);
|
||||
|
||||
#undef set_opcode
|
||||
|
||||
dprintf("cx23882_risc_ram_setup leave\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cx23882_via_sis_fixup(cx23882_device *device)
|
||||
{
|
||||
uint16 host_vendor;
|
||||
uint32 dev_cntrl1;
|
||||
|
||||
host_vendor = gPci->read_pci_config(0, 0, 0, PCI_vendor_id, 2);
|
||||
dev_cntrl1 = reg_read32(REG_F2_DEV_CNTRL1);
|
||||
|
||||
if (host_vendor == PCI_VENDOR_VIA || host_vendor == PCI_VENDOR_SIS) {
|
||||
dprintf("cx23882: enabling VIA/SIS compatibility mode\n");
|
||||
reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 | F2_DEV_CNTRL1_EN_VSFX);
|
||||
} else {
|
||||
dprintf("cx23882: disabling VIA/SIS compatibility mode\n");
|
||||
reg_write32(REG_F2_DEV_CNTRL1, dev_cntrl1 & ~F2_DEV_CNTRL1_EN_VSFX);
|
||||
}
|
||||
}
|
72
src/add-ons/kernel/drivers/dvb/cx23882/cx23882.h
Normal file
72
src/add-ons/kernel/drivers/dvb/cx23882/cx23882.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __CX23882_H
|
||||
#define __CX23882_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include "driver.h"
|
||||
#include "cx23882_regs.h"
|
||||
#include "i2c-core.h"
|
||||
|
||||
typedef struct {
|
||||
const pci_info * pci_info;
|
||||
int irq;
|
||||
void * regs;
|
||||
area_id regs_area;
|
||||
uint32 i2c_reg;
|
||||
i2c_bus * i2c_bus;
|
||||
|
||||
area_id dma_buf1_area;
|
||||
void * dma_buf1_virt;
|
||||
void * dma_buf1_phys;
|
||||
area_id dma_buf2_area;
|
||||
void * dma_buf2_virt;
|
||||
void * dma_buf2_phys;
|
||||
|
||||
sem_id capture_sem;
|
||||
void * capture_data;
|
||||
size_t capture_size;
|
||||
bigtime_t capture_end_time;
|
||||
} cx23882_device;
|
||||
|
||||
|
||||
#define reg_read8(offset) (*(volatile uint8 *) ((char *)(device->regs) + (offset)))
|
||||
#define reg_read16(offset) (*(volatile uint16 *)((char *)(device->regs) + (offset)))
|
||||
#define reg_read32(offset) (*(volatile uint32 *)((char *)(device->regs) + (offset)))
|
||||
#define reg_write8(offset, value) (*(volatile uint8 *) ((char *)(device->regs) + (offset)) = value)
|
||||
#define reg_write16(offset, value) (*(volatile uint16 *)((char *)(device->regs) + (offset)) = value)
|
||||
#define reg_write32(offset, value) (*(volatile uint32 *)((char *)(device->regs) + (offset)) = value)
|
||||
|
||||
|
||||
void cx23882_reset(cx23882_device *device);
|
||||
status_t cx23882_init(cx23882_device *device);
|
||||
status_t cx23882_terminate(cx23882_device *device);
|
||||
|
||||
status_t cx23882_start_capture(cx23882_device *device);
|
||||
status_t cx23882_stop_capture(cx23882_device *device);
|
||||
|
||||
int32 cx23882_int(void *data);
|
||||
|
||||
#endif
|
90
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_i2c.c
Normal file
90
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_i2c.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "i2c.h"
|
||||
#include "i2c-core.h"
|
||||
|
||||
|
||||
static void
|
||||
set_scl(void *cookie, int state)
|
||||
{
|
||||
cx23882_device * device = cookie;
|
||||
if (state)
|
||||
device->i2c_reg |= I2C_SCL;
|
||||
else
|
||||
device->i2c_reg &= ~I2C_SCL;
|
||||
reg_write32(REG_I2C_CONTROL, device->i2c_reg);
|
||||
reg_read32(REG_I2C_CONTROL); // PCI bridge flush
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_sda(void *cookie, int state)
|
||||
{
|
||||
cx23882_device * device = cookie;
|
||||
if (state)
|
||||
device->i2c_reg |= I2C_SDA;
|
||||
else
|
||||
device->i2c_reg &= ~I2C_SDA;
|
||||
reg_write32(REG_I2C_CONTROL, device->i2c_reg);
|
||||
reg_read32(REG_I2C_CONTROL); // PCI bridge flush
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_scl(void *cookie)
|
||||
{
|
||||
cx23882_device * device = cookie;
|
||||
return (reg_read32(REG_I2C_CONTROL) & I2C_SCL) >> 1; // I2C_SCL is 0x02
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_sda(void *cookie)
|
||||
{
|
||||
cx23882_device * device = cookie;
|
||||
return reg_read32(REG_I2C_CONTROL) & I2C_SDA; // I2C_SDA is 0x01
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_init(cx23882_device *device)
|
||||
{
|
||||
device->i2c_bus = i2c_create_bus(device, 80000, 2000000, set_scl, set_sda, get_scl, get_sda);
|
||||
device->i2c_reg = reg_read32(REG_I2C_CONTROL);
|
||||
device->i2c_reg &= ~I2C_HW_MODE;
|
||||
device->i2c_reg |= I2C_SCL | I2C_SDA;
|
||||
reg_write32(REG_I2C_CONTROL, device->i2c_reg);
|
||||
reg_read32(REG_I2C_CONTROL); // PCI bridge flush
|
||||
return device->i2c_bus ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
i2c_terminate(cx23882_device *device)
|
||||
{
|
||||
i2c_delete_bus(device->i2c_bus);
|
||||
}
|
||||
|
||||
|
33
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_i2c.h
Normal file
33
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_i2c.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __I2C_H
|
||||
#define __I2C_H
|
||||
|
||||
#include "cx23882.h"
|
||||
|
||||
status_t i2c_init(cx23882_device *device);
|
||||
void i2c_terminate(cx23882_device *device);
|
||||
|
||||
#endif
|
144
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_regs.h
Normal file
144
src/add-ons/kernel/drivers/dvb/cx23882/cx23882_regs.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __CX23882_REGS_H
|
||||
#define __CX23882_REGS_H
|
||||
|
||||
#define PCI_PCICMD_IOS 0x01
|
||||
#define PCI_PCICMD_MSE 0x02
|
||||
#define PCI_PCICMD_BME 0x04
|
||||
|
||||
#define PCI_VENDOR_SIS 0x1039
|
||||
#define PCI_VENDOR_VIA 0x1106
|
||||
|
||||
#define REG_PDMA_STHRSH 0x200000
|
||||
#define REG_PDMA_DTHRSH 0x200010
|
||||
|
||||
#define PDMA_ISBTHRSH_1 0x0100
|
||||
#define PDMA_ISBTHRSH_2 0x0200
|
||||
#define PDMA_ISBTHRSH_3 0x0300
|
||||
#define PDMA_ISBTHRSH_4 0x0400
|
||||
#define PDMA_ISBTHRSH_5 0x0500
|
||||
#define PDMA_ISBTHRSH_6 0x0600
|
||||
#define PDMA_ISBTHRSH_7 0x0700
|
||||
|
||||
#define PDMA_PCITHRSH_1 0x0001
|
||||
#define PDMA_PCITHRSH_2 0x0002
|
||||
#define PDMA_PCITHRSH_3 0x0003
|
||||
#define PDMA_PCITHRSH_4 0x0004
|
||||
#define PDMA_PCITHRSH_5 0x0005
|
||||
#define PDMA_PCITHRSH_6 0x0006
|
||||
#define PDMA_PCITHRSH_7 0x0007
|
||||
|
||||
#define REG_DEV_CNTRL2 0x200034
|
||||
|
||||
#define DEV_CNTRL2_RUN_RISC 0x20
|
||||
|
||||
#define REG_PCI_INT_MSK 0x200040
|
||||
#define REG_PCI_INT_STAT 0x200044
|
||||
#define REG_PCI_INT_MSTAT 0x200048
|
||||
|
||||
#define PCI_INT_STAT_VID_INT 0x01
|
||||
#define PCI_INT_STAT_AUD_INT 0x02
|
||||
#define PCI_INT_STAT_TS_INT 0x04
|
||||
#define PCI_INT_STAT_VIP_INT 0x08
|
||||
#define PCI_INT_STAT_HST_INT 0x10
|
||||
|
||||
#define REG_VID_INT_MSK 0x200050
|
||||
#define REG_VID_INT_STAT 0x200054
|
||||
#define REG_VID_INT_MSTAT 0x200058
|
||||
|
||||
#define REG_AUD_INT_MSK 0x200060
|
||||
#define REG_AUD_INT_STAT 0x200064
|
||||
#define REG_AUD_INT_MSTAT 0x200068
|
||||
|
||||
#define REG_TS_INT_MSK 0x200070
|
||||
#define REG_TS_INT_STAT 0x200074
|
||||
#define REG_TS_INT_MSTAT 0x200078
|
||||
|
||||
#define TS_INT_STAT_TS_RISC1 0x000001
|
||||
#define TS_INT_STAT_TS_RISC2 0x000010
|
||||
#define TS_INT_STAT_OPC_ERR 0x010000
|
||||
|
||||
#define REG_VIP_INT_MSK 0x200080
|
||||
#define REG_VIP_INT_STAT 0x200084
|
||||
#define REG_VIP_INT_MSTAT 0x200088
|
||||
|
||||
#define REG_HST_INT_MSK 0x200090
|
||||
#define REG_HST_INT_STAT 0x200094
|
||||
#define REG_HST_INT_MSTAT 0x200098
|
||||
|
||||
#define REG_F2_DEV_CNTRL1 0x2f0240
|
||||
#define F2_DEV_CNTRL1_EN_VSFX 0x8
|
||||
|
||||
#define REG_DMA28_PTR1 0x30009c
|
||||
#define REG_DMA28_PTR2 0x3000dc
|
||||
#define REG_DMA28_CNT1 0x30011c
|
||||
#define REG_DMA28_CNT2 0x30015c
|
||||
|
||||
#define REG_TS_GP_CNT_CNTRL 0x33c030
|
||||
#define REG_TS_DMA_CNTRL 0x33c040
|
||||
|
||||
#define TS_DMA_CNTRL_TS_FIFO_EN 0x01
|
||||
#define TS_DMA_CNTRL_TS_RISC_EN 0x10
|
||||
|
||||
#define REG_TS_LNGTH 0x33c048
|
||||
#define REG_HW_SOP_CONTROL 0x33c04c
|
||||
#define REG_TS_GEN_CONTROL 0x33c050
|
||||
|
||||
#define TS_GEN_CONTROL_IPB_SMODE 0x08
|
||||
|
||||
#define REG_TS_BD_PKT_STATUS 0x33c054
|
||||
#define REG_TS_SOP_STATUS 0x33c058
|
||||
|
||||
#define REG_VIP_STREAM_EN 0x34c040
|
||||
|
||||
// these 3 are not in my spec, taken form Linux
|
||||
#define REG_DMA_RISC_INT_MSK 0x35C060
|
||||
#define REG_DMA_RISC_INT_STAT 0x35C064
|
||||
#define REG_DMA_RISC_INT_MSTAT 0x35C068
|
||||
|
||||
#define REG_I2C_CONTROL 0x368000
|
||||
#define I2C_SDA 0x01
|
||||
#define I2C_SCL 0x02
|
||||
#define I2C_HW_MODE 0x80
|
||||
|
||||
#define REG_HST_STREAM_EN 0x38c040
|
||||
|
||||
|
||||
// RISC instructions
|
||||
#define RISC_RESYNC 0x80008000
|
||||
#define RISC_WRITE 0x10000000
|
||||
#define RISC_SKIP 0x20000000
|
||||
#define RISC_JUMP 0x70000000
|
||||
#define RISC_WRITECR 0xd0000000
|
||||
|
||||
#define RISC_IMM 0x00000001
|
||||
#define RISC_SOL 0x08000000
|
||||
#define RISC_EOL 0x04000000
|
||||
#define RISC_IRQ2 0x02000000
|
||||
#define RISC_IRQ1 0x01000000
|
||||
#define RISC_SRP 0x00000001
|
||||
|
||||
#endif
|
301
src/add-ons/kernel/drivers/dvb/cx23882/driver.c
Normal file
301
src/add-ons/kernel/drivers/dvb/cx23882/driver.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <Drivers.h>
|
||||
#include <Errors.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "config.h"
|
||||
#include "driver.h"
|
||||
#include "mktime.h"
|
||||
|
||||
#define TRACE_DRIVER
|
||||
#ifdef TRACE_DRIVER
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vendor;
|
||||
int device;
|
||||
int subvendor;
|
||||
int subdevice;
|
||||
const char *name;
|
||||
} card_info;
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
pci_module_info * gPci;
|
||||
static char * sDevNameList[MAX_CARDS + 1];
|
||||
static pci_info * sDevList[MAX_CARDS];
|
||||
static int32 sOpenMask;
|
||||
|
||||
static card_info sCardTable[] =
|
||||
{
|
||||
{ 0x14f1, 0x8802, 0x0070, 0x9002, "Hauppauge WinTV-NOVA-T model 928" },
|
||||
{ /* end */ }
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * cookie;
|
||||
int dev_id;
|
||||
} interface_cookie;
|
||||
|
||||
|
||||
static const char *
|
||||
identify_device(const card_info *cards, const pci_info *info)
|
||||
{
|
||||
for (; cards->name; cards++) {
|
||||
if (cards->vendor >= 0 && cards->vendor != info->vendor_id)
|
||||
continue;
|
||||
if (cards->device >= 0 && cards->device != info->device_id)
|
||||
continue;
|
||||
if ((info->header_type & PCI_header_type_mask) != PCI_header_type_generic)
|
||||
continue;
|
||||
if (cards->subvendor >= 0 && cards->subvendor != info->u.h0.subsystem_vendor_id)
|
||||
continue;
|
||||
if (cards->subdevice >= 0 && cards->subdevice != info->u.h0.subsystem_id)
|
||||
continue;
|
||||
return cards->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_hardware(void)
|
||||
{
|
||||
pci_info info;
|
||||
status_t res;
|
||||
int i;
|
||||
|
||||
TRACE("cx23882: init_hardware()\n");
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK)
|
||||
return B_ERROR;
|
||||
for (res = B_ERROR, i = 0; gPci->get_nth_pci_info(i, &info) == B_OK; i++) {
|
||||
if (identify_device(sCardTable, &info)) {
|
||||
res = B_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
gPci = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
init_driver(void)
|
||||
{
|
||||
struct pci_info *item;
|
||||
int index;
|
||||
int cards;
|
||||
|
||||
#ifdef DEBUG
|
||||
set_dprintf_enabled(true);
|
||||
load_driver_symbols("cx23882");
|
||||
#endif
|
||||
|
||||
dprintf(gBanner);
|
||||
|
||||
item = (pci_info *)malloc(sizeof(pci_info));
|
||||
if (!item)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK) {
|
||||
free(item);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
for (cards = 0, index = 0; gPci->get_nth_pci_info(index++, item) == B_OK; ) {
|
||||
const char *info = identify_device(sCardTable, item);
|
||||
if (info) {
|
||||
char name[64];
|
||||
sprintf(name, "dvb/cx23882/%d", cards + 1);
|
||||
dprintf("cx23882: /dev/%s is a %s\n", name, info);
|
||||
sDevList[cards] = item;
|
||||
sDevNameList[cards] = strdup(name);
|
||||
sDevNameList[cards + 1] = NULL;
|
||||
cards++;
|
||||
item = (pci_info *)malloc(sizeof(pci_info));
|
||||
if (!item)
|
||||
goto err_outofmem;
|
||||
if (cards == MAX_CARDS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(item);
|
||||
|
||||
if (!cards)
|
||||
goto err_cards;
|
||||
|
||||
return B_OK;
|
||||
|
||||
err_outofmem:
|
||||
TRACE("cx23882: err_outofmem\n");
|
||||
for (index = 0; index < cards; index++) {
|
||||
free(sDevList[index]);
|
||||
free(sDevNameList[index]);
|
||||
}
|
||||
err_cards:
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_driver(void)
|
||||
{
|
||||
int32 i;
|
||||
|
||||
TRACE("cx23882: uninit_driver\n");
|
||||
|
||||
for (i = 0; sDevNameList[i] != NULL; i++) {
|
||||
free(sDevList[i]);
|
||||
free(sDevNameList[i]);
|
||||
}
|
||||
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_open(const char *name, uint32 flags, void** _cookie)
|
||||
{
|
||||
interface_cookie *cookie;
|
||||
char *deviceName;
|
||||
status_t status;
|
||||
int dev_id;
|
||||
int mask;
|
||||
|
||||
TRACE("cx23882: driver open\n");
|
||||
|
||||
for (dev_id = 0; (deviceName = sDevNameList[dev_id]) != NULL; dev_id++) {
|
||||
if (!strcmp(name, deviceName))
|
||||
break;
|
||||
}
|
||||
if (deviceName == NULL) {
|
||||
TRACE("cx23882: invalid device name\n");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// allow only one concurrent access
|
||||
mask = 1 << dev_id;
|
||||
if (atomic_or(&sOpenMask, mask) & mask)
|
||||
return B_BUSY;
|
||||
|
||||
cookie = (interface_cookie *)malloc(sizeof(interface_cookie));
|
||||
if (!cookie)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
cookie->dev_id = dev_id;
|
||||
status = interface_attach(&cookie->cookie, sDevList[dev_id]);
|
||||
if (status != B_OK) {
|
||||
free(cookie);
|
||||
atomic_and(&sOpenMask, ~(1 << dev_id));
|
||||
return status;
|
||||
}
|
||||
|
||||
*_cookie = cookie;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_close(void* cookie)
|
||||
{
|
||||
TRACE("cx23882: driver close\n");
|
||||
interface_detach(((interface_cookie *)cookie)->cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_free(void* cookie)
|
||||
{
|
||||
TRACE("cx23882: driver free\n");
|
||||
atomic_and(&sOpenMask, ~(1 << ((interface_cookie *)cookie)->dev_id));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_read(void* cookie, off_t position, void *buf, size_t* num_bytes)
|
||||
{
|
||||
TRACE("cx23882: driver read\n");
|
||||
*num_bytes = 0; // required by design for read hook!
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes)
|
||||
{
|
||||
TRACE("cx23882: driver write\n");
|
||||
*num_bytes = 0; // not sure if required for write hook
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
driver_control(void *cookie, uint32 op, void *arg, size_t len)
|
||||
{
|
||||
// TRACE("cx23882: driver control\n");
|
||||
return interface_ioctl(((interface_cookie *)cookie)->cookie, op, arg, len);
|
||||
}
|
||||
|
||||
|
||||
static device_hooks
|
||||
sDeviceHooks = {
|
||||
driver_open,
|
||||
driver_close,
|
||||
driver_free,
|
||||
driver_control,
|
||||
driver_read,
|
||||
driver_write,
|
||||
};
|
||||
|
||||
|
||||
const char**
|
||||
publish_devices(void)
|
||||
{
|
||||
return (const char**)sDevNameList;
|
||||
}
|
||||
|
||||
|
||||
device_hooks*
|
||||
find_device(const char* name)
|
||||
{
|
||||
return &sDeviceHooks;
|
||||
}
|
32
src/add-ons/kernel/drivers/dvb/cx23882/driver.h
Normal file
32
src/add-ons/kernel/drivers/dvb/cx23882/driver.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __DRIVER_H
|
||||
#define __DRIVER_H
|
||||
|
||||
#include <PCI.h>
|
||||
|
||||
extern pci_module_info *gPci;
|
||||
|
||||
#endif
|
168
src/add-ons/kernel/drivers/dvb/cx23882/dtt7592.c
Normal file
168
src/add-ons/kernel/drivers/dvb/cx23882/dtt7592.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include "dtt7592.h"
|
||||
#include "config.h"
|
||||
|
||||
#define TRACE_DTT7592
|
||||
#ifdef TRACE_DTT7592
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
|
||||
status_t
|
||||
dtt7592_write(i2c_bus *bus, const uint8 data[4])
|
||||
{
|
||||
status_t res;
|
||||
TRACE("dtt7592_write values 0x%02x 0x%02x 0x%02x 0x%02x\n", data[0], data[1], data[2], data[3]);
|
||||
res = i2c_write(bus, I2C_ADDR_PLL, data, 4);
|
||||
if (res != B_OK)
|
||||
TRACE("dtt7592_write error, values 0x%02x 0x%02x 0x%02x 0x%02x\n", data[0], data[1], data[2], data[3]);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dtt7592_read(i2c_bus *bus, uint8 *data)
|
||||
{
|
||||
status_t res;
|
||||
res = i2c_read(bus, I2C_ADDR_PLL, data, 1);
|
||||
if (res != B_OK)
|
||||
TRACE("dtt7592_read error\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
dtt7592_set_frequency(i2c_bus *bus, uint32 frequency, dvb_bandwidth_t bandwidth)
|
||||
{
|
||||
status_t res;
|
||||
uint32 divider;
|
||||
uint8 data[4];
|
||||
|
||||
divider = (frequency + 36083333) / 166666;
|
||||
if (divider > 0x7fff)
|
||||
divider = 0x7fff;
|
||||
|
||||
TRACE("dtt7592_set_frequency frequency %ld, divider 0x%lx (%ld)\n", frequency, divider, divider);
|
||||
|
||||
data[0] = divider >> 8;
|
||||
data[1] = (uint8)divider;
|
||||
|
||||
if (frequency > 835000000)
|
||||
data[2] = 0xfc;
|
||||
else if (frequency > 735000000)
|
||||
data[2] = 0xf4;
|
||||
else if (frequency > 465000000)
|
||||
data[2] = 0xbc;
|
||||
else if (frequency > 445000000)
|
||||
data[2] = 0xfc;
|
||||
else if (frequency > 405000000)
|
||||
data[2] = 0xf4;
|
||||
else if (frequency > 305000000)
|
||||
data[2] = 0xbc;
|
||||
else
|
||||
data[2] = 0xb4;
|
||||
|
||||
if (frequency > 429000000)
|
||||
data[3] = 0x08; // select UHF IV/V
|
||||
else
|
||||
data[3] = 0x02; // select VHF III
|
||||
|
||||
// only used in Germany right now, where VHF channels
|
||||
// are 7 MHz wide, while UHF are 8 MHz.
|
||||
if (bandwidth == DVB_BANDWIDTH_5_MHZ
|
||||
|| bandwidth == DVB_BANDWIDTH_6_MHZ
|
||||
|| bandwidth == DVB_BANDWIDTH_7_MHZ) {
|
||||
data[3] |= 0x10; // activate 7 Mhz filter
|
||||
}
|
||||
|
||||
res = dtt7592_write(bus, data);
|
||||
if (res != B_OK) {
|
||||
dprintf("dtt7592_set_frequency step 1 failed\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
// enable AGC
|
||||
data[2] = (data[2] & 0x40) | 0x9c;
|
||||
data[3] = 0xa0;
|
||||
res = dtt7592_write(bus, data);
|
||||
if (res != B_OK) {
|
||||
dprintf("dtt7592_set_frequency step 2 failed\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
// wait 100 ms
|
||||
snooze(100000);
|
||||
|
||||
// disable AGC
|
||||
data[3] = 0x20;
|
||||
res = dtt7592_write(bus, data);
|
||||
if (res != B_OK) {
|
||||
dprintf("dtt7592_set_frequency step 3 failed\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtt7582_dump(i2c_bus *bus)
|
||||
{
|
||||
uint8 data;
|
||||
if (B_OK != dtt7592_read(bus, &data)) {
|
||||
TRACE("dtt7582_dump failed\n");
|
||||
}
|
||||
TRACE("dtt7582_dump: 0x%02x, PLL %s, AGC %s\n", data, (data & 0x40) ? "locked" : "open", (data & 0x08) ? "active" : "off");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dtt7582_test(i2c_bus *bus)
|
||||
{
|
||||
TRACE("dtt7582_test start\n");
|
||||
dtt7582_dump(bus);
|
||||
TRACE("dtt7582_test freq 1\n");
|
||||
dtt7592_set_frequency(bus, 150000000, DVB_BANDWIDTH_7_MHZ);
|
||||
dtt7582_dump(bus);
|
||||
TRACE("dtt7582_test freq 2\n");
|
||||
dtt7592_set_frequency(bus, 746000000, DVB_BANDWIDTH_8_MHZ); // Kabel 1
|
||||
dtt7582_dump(bus);
|
||||
TRACE("dtt7582_test freq 3\n");
|
||||
dtt7592_set_frequency(bus, 538000000, DVB_BANDWIDTH_7_MHZ); // VOX
|
||||
dtt7582_dump(bus);
|
||||
TRACE("dtt7582_test freq 4\n");
|
||||
dtt7592_set_frequency(bus, 896000000, DVB_BANDWIDTH_8_MHZ);
|
||||
dtt7582_dump(bus);
|
||||
TRACE("dtt7582_test freq 5\n");
|
||||
dtt7592_set_frequency(bus, 333000000, DVB_BANDWIDTH_7_MHZ);
|
||||
dtt7582_dump(bus);
|
||||
}
|
||||
|
||||
|
||||
|
38
src/add-ons/kernel/drivers/dvb/cx23882/dtt7592.h
Normal file
38
src/add-ons/kernel/drivers/dvb/cx23882/dtt7592.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __DTT7592_H
|
||||
#define __DTT7592_H
|
||||
|
||||
#include "i2c-core.h"
|
||||
#include "dvb.h"
|
||||
|
||||
status_t dtt7592_write(i2c_bus *bus, const uint8 data[4]);
|
||||
status_t dtt7592_read(i2c_bus *bus, uint8 *data);
|
||||
|
||||
status_t dtt7592_set_frequency(i2c_bus *bus, uint32 frequency, dvb_bandwidth_t bandwidth);
|
||||
|
||||
void dtt7582_test(i2c_bus *bus);
|
||||
|
||||
#endif
|
321
src/add-ons/kernel/drivers/dvb/cx23882/dvb_interface.c
Normal file
321
src/add-ons/kernel/drivers/dvb/cx23882/dvb_interface.c
Normal file
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <stdlib.h>
|
||||
#include "interface.h"
|
||||
#include "cx23882.h"
|
||||
#include "cx22702.h"
|
||||
#include "dtt7592.h"
|
||||
#include "driver.h"
|
||||
#include "config.h"
|
||||
#include "util.h"
|
||||
#include "i2c.h"
|
||||
|
||||
#define TRACE_INTERFACE
|
||||
#ifdef TRACE_INTERFACE
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
static inline status_t user_memcpy(void *d, const void *s, size_t z) { memcpy(d, s, z); return B_OK; }
|
||||
#define B_BAD_ADDRESS B_ERROR
|
||||
|
||||
static void
|
||||
dump_eeprom(cx23882_device *device)
|
||||
{
|
||||
uint8 d[256+8];
|
||||
uint8 adr;
|
||||
uint8 *p;
|
||||
int i;
|
||||
status_t res;
|
||||
|
||||
adr = 0;
|
||||
res = i2c_xfer(device->i2c_bus, I2C_ADDR_EEPROM, &adr, 1, d, sizeof(d));
|
||||
if (res != B_OK) {
|
||||
TRACE("i2c_read failed: %08lx\n", res);
|
||||
return;
|
||||
}
|
||||
for (p = d, i = 0; i < ((int)sizeof(d) / 8); i++, p+= 8)
|
||||
TRACE("EEPROM %02x: %02x %02x %02x %02x %02x %02x %02x %02x\n", i * 8, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
interface_attach(void **cookie, const pci_info *info)
|
||||
{
|
||||
cx23882_device *device;
|
||||
uint32 val;
|
||||
int i;
|
||||
|
||||
TRACE("interface_attach\n");
|
||||
|
||||
device = malloc(sizeof(cx23882_device));
|
||||
if (!device)
|
||||
return B_NO_MEMORY;
|
||||
*cookie = device;
|
||||
|
||||
// initialize cookie
|
||||
memset(device, 0, sizeof(*device));
|
||||
device->regs_area = -1;
|
||||
device->dma_buf1_area = -1;
|
||||
device->dma_buf2_area = -1;
|
||||
device->capture_sem = -1;
|
||||
|
||||
device->pci_info = info;
|
||||
|
||||
// enable busmaster and memory mapped access, disable io port access
|
||||
val = gPci->read_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, PCI_command, 2);
|
||||
val = PCI_PCICMD_BME | PCI_PCICMD_MSE | (val & ~PCI_PCICMD_IOS);
|
||||
gPci->write_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, PCI_command, 2, val);
|
||||
|
||||
// adjust PCI latency timer
|
||||
val = gPci->read_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, PCI_latency, 1);
|
||||
TRACE("PCI latency is %02lx, changing to %02x\n", val, PCI_LATENCY);
|
||||
gPci->write_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, PCI_latency, 1, PCI_LATENCY);
|
||||
|
||||
// get IRQ
|
||||
device->irq = gPci->read_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, PCI_interrupt_line, 1);
|
||||
if (device->irq == 0 || device->irq == 0xff) {
|
||||
dprintf("cx23882: Error, no IRQ assigned\n");
|
||||
goto err;
|
||||
}
|
||||
TRACE("IRQ %d\n", device->irq);
|
||||
|
||||
// map registers into memory
|
||||
val = gPci->read_pci_config(device->pci_info->bus, device->pci_info->device, device->pci_info->function, 0x10, 4);
|
||||
val &= PCI_address_memory_32_mask;
|
||||
if (val == 0) {
|
||||
dprintf("cx23882: Error, no memory space assigned\n");
|
||||
goto err;
|
||||
}
|
||||
TRACE("hardware register address %p\n", (void *) val);
|
||||
device->regs_area = map_mem(&device->regs, (void *)val, 16777216 /* 16 MB */, 0, "cx23882 registers");
|
||||
if (device->regs_area < B_OK) {
|
||||
dprintf("cx23882: Error, can't map hardware registers\n");
|
||||
goto err;
|
||||
}
|
||||
TRACE("mapped registers to %p\n", device->regs);
|
||||
|
||||
device->capture_sem = create_sem(0, "cx23882 capture");
|
||||
|
||||
cx23882_reset(device);
|
||||
|
||||
if (i2c_init(device) < B_OK) {
|
||||
dprintf("cx23882: Error, can't init I2C\n");
|
||||
}
|
||||
|
||||
|
||||
if (cx23882_init(device) < B_OK) {
|
||||
dprintf("cx23882: Error, can't init hardware\n");
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
if (cx22702_init(device->i2c_bus) == B_OK)
|
||||
break;
|
||||
if (i == 20) {
|
||||
TRACE("cx22702_init failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// setup interrupt handler
|
||||
if (install_io_interrupt_handler(device->irq, cx23882_int, device, 0) < B_OK) {
|
||||
dprintf("cx23882: Error, can't install interrupt handler\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// dump_eeprom(device);
|
||||
// dtt7582_test(device->i2c_bus);
|
||||
|
||||
return B_OK;
|
||||
err:
|
||||
free(cookie);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
interface_detach(void *cookie)
|
||||
{
|
||||
cx23882_device *device = cookie;
|
||||
|
||||
i2c_terminate(device);
|
||||
|
||||
if (cx23882_terminate(device) < B_OK) {
|
||||
}
|
||||
|
||||
remove_io_interrupt_handler(device->irq, cx23882_int, device);
|
||||
|
||||
delete_area(device->regs_area);
|
||||
|
||||
delete_sem(device->capture_sem);
|
||||
|
||||
TRACE("interface_detach\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
interface_get_interface_info(dvb_interface_info_t *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->version = 1;
|
||||
info->flags = 0;
|
||||
info->type = DVB_TYPE_DVB_T;
|
||||
strcpy(info->name, "CX23882");
|
||||
strcpy(info->info, "Hauppauge WinTV-NOVA-T model 928 driver, Copyright (c) 2005 Marcus Overhagen");
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
interface_ioctl(void *cookie, uint32 op, void *arg, size_t len)
|
||||
{
|
||||
cx23882_device *device = cookie;
|
||||
status_t res;
|
||||
|
||||
switch (op) {
|
||||
case DVB_GET_INTERFACE_INFO:
|
||||
{
|
||||
dvb_interface_info_t info;
|
||||
interface_get_interface_info(&info);
|
||||
if (user_memcpy(arg, &info, sizeof(info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_FREQUENCY_INFO:
|
||||
{
|
||||
dvb_frequency_info_t info;
|
||||
if ((res = cx22702_get_frequency_info(device->i2c_bus, &info)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &info, sizeof(info)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_START_CAPTURE:
|
||||
{
|
||||
return cx23882_start_capture(device);
|
||||
}
|
||||
|
||||
case DVB_STOP_CAPTURE:
|
||||
{
|
||||
return cx23882_stop_capture(device);
|
||||
}
|
||||
|
||||
case DVB_SET_TUNING_PARAMETERS:
|
||||
{
|
||||
dvb_tuning_parameters_t params;
|
||||
if (user_memcpy(¶ms, arg, sizeof(params)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
if ((res = cx22702_set_tuning_parameters(device->i2c_bus, ¶ms.u.dvb_t)) < B_OK)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_TUNING_PARAMETERS:
|
||||
{
|
||||
dvb_tuning_parameters_t params;
|
||||
if ((res = cx22702_get_tuning_parameters(device->i2c_bus, ¶ms.u.dvb_t)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, ¶ms, sizeof(params)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_STATUS:
|
||||
{
|
||||
dvb_status_t status;
|
||||
if ((res = cx22702_get_status(device->i2c_bus, &status)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &status, sizeof(status)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_SS:
|
||||
{
|
||||
uint32 value;
|
||||
if ((res = cx22702_get_ss(device->i2c_bus, &value)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &value, sizeof(value)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_BER:
|
||||
{
|
||||
uint32 value;
|
||||
if ((res = cx22702_get_ber(device->i2c_bus, &value)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &value, sizeof(value)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_SNR:
|
||||
{
|
||||
uint32 value;
|
||||
if ((res = cx22702_get_snr(device->i2c_bus, &value)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &value, sizeof(value)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_GET_UPC:
|
||||
{
|
||||
uint32 value;
|
||||
if ((res = cx22702_get_upc(device->i2c_bus, &value)) < B_OK)
|
||||
return res;
|
||||
if (user_memcpy(arg, &value, sizeof(value)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DVB_CAPTURE:
|
||||
{
|
||||
dvb_capture_t cap_data;
|
||||
// wait for data ready interrupt, with 100 ms timeout (in case tuning failed, bad reception, etc)
|
||||
if ((res = acquire_sem_etc(device->capture_sem, 1, B_CAN_INTERRUPT | B_RELATIVE_TIMEOUT, 100000)) < B_OK)
|
||||
return res;
|
||||
cap_data.data = device->capture_data;
|
||||
cap_data.size = device->capture_size;
|
||||
cap_data.end_time = device->capture_end_time;
|
||||
if (user_memcpy(arg, &cap_data, sizeof(cap_data)) < B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
TRACE("interface_ioctl\n");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
32
src/add-ons/kernel/drivers/dvb/cx23882/dvb_interface.h
Normal file
32
src/add-ons/kernel/drivers/dvb/cx23882/dvb_interface.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __DVB_INTERFACE_H
|
||||
#define __DVB_INTERFACE_H
|
||||
|
||||
status_t interface_attach(void **cookie, const pci_info *info);
|
||||
void interface_detach(void *cookie);
|
||||
status_t interface_ioctl(void *cookie, uint32 op, void *arg, size_t len);
|
||||
|
||||
#endif
|
394
src/add-ons/kernel/drivers/dvb/cx23882/i2c_core.c
Normal file
394
src/add-ons/kernel/drivers/dvb/cx23882/i2c_core.c
Normal file
@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <KernelExport.h>
|
||||
#include "i2c-core.h"
|
||||
|
||||
#define TRACE_I2C
|
||||
#ifdef TRACE_I2C
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
static status_t i2c_writebyte(i2c_bus *bus, uint8 byte, int *ack);
|
||||
static status_t i2c_readbyte(i2c_bus *bus, uint8 *pbyte);
|
||||
static status_t i2c_read_unlocked(i2c_bus *bus, int address, void *data, int size);
|
||||
static status_t i2c_write_unlocked(i2c_bus *bus, int address, const void *data, int size);
|
||||
|
||||
|
||||
struct _i2c_bus
|
||||
{
|
||||
void *cookie;
|
||||
bigtime_t delay;
|
||||
bigtime_t timeout;
|
||||
i2c_set_scl set_scl;
|
||||
i2c_set_sda set_sda;
|
||||
i2c_get_scl get_scl;
|
||||
i2c_get_sda get_sda;
|
||||
sem_id sem;
|
||||
};
|
||||
|
||||
|
||||
i2c_bus *
|
||||
i2c_create_bus(void *cookie,
|
||||
int frequency,
|
||||
bigtime_t timeout,
|
||||
i2c_set_scl set_scl,
|
||||
i2c_set_sda set_sda,
|
||||
i2c_get_scl get_scl,
|
||||
i2c_get_sda get_sda)
|
||||
{
|
||||
i2c_bus *bus = malloc(sizeof(i2c_bus));
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
bus->sem = create_sem(1, "i2c bus access");
|
||||
if (bus->sem < 0) {
|
||||
free(bus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bus->cookie = cookie;
|
||||
bus->delay = 1000000 / frequency;
|
||||
if (bus->delay == 0)
|
||||
bus->delay = 1;
|
||||
bus->timeout = timeout;
|
||||
bus->set_scl = set_scl;
|
||||
bus->set_sda = set_sda;
|
||||
bus->get_scl = get_scl;
|
||||
bus->get_sda = get_sda;
|
||||
|
||||
set_scl(cookie, 1);
|
||||
set_sda(cookie, 1);
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
i2c_delete_bus(i2c_bus *bus)
|
||||
{
|
||||
if (!bus)
|
||||
return;
|
||||
delete_sem(bus->sem);
|
||||
free(bus);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_sda_low(i2c_bus *bus)
|
||||
{
|
||||
bus->set_sda(bus->cookie, 0);
|
||||
snooze(bus->delay);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_sda_high(i2c_bus *bus)
|
||||
{
|
||||
bus->set_sda(bus->cookie, 1);
|
||||
snooze(bus->delay);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_scl_low(i2c_bus *bus)
|
||||
{
|
||||
bus->set_scl(bus->cookie, 0);
|
||||
snooze(bus->delay);
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
set_scl_high(i2c_bus *bus)
|
||||
{
|
||||
bigtime_t end = system_time() + bus->timeout;
|
||||
bus->set_scl(bus->cookie, 1);
|
||||
while (0 == bus->get_scl(bus->cookie)) {
|
||||
if (system_time() > end)
|
||||
return B_TIMED_OUT;
|
||||
snooze(5);
|
||||
}
|
||||
snooze(bus->delay);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
i2c_start(i2c_bus *bus)
|
||||
{
|
||||
set_sda_low(bus);
|
||||
set_scl_low(bus);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
i2c_stop(i2c_bus *bus)
|
||||
{
|
||||
set_sda_low(bus);
|
||||
set_scl_high(bus);
|
||||
set_sda_high(bus);
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
i2c_start_address(i2c_bus *bus, int address, int read /* 1 = read, 0 = write */)
|
||||
{
|
||||
status_t res;
|
||||
uint8 addr;
|
||||
int ack;
|
||||
int i;
|
||||
|
||||
// TRACE("i2c_start_address: enter\n");
|
||||
|
||||
addr = (address << 1) | (read & 1);
|
||||
for (i = 0; i < 5; i++) {
|
||||
i2c_start(bus);
|
||||
res = i2c_writebyte(bus, addr, &ack);
|
||||
if (res == B_OK) {
|
||||
if (ack)
|
||||
break;
|
||||
res = B_ERROR;
|
||||
}
|
||||
if (res == B_TIMED_OUT)
|
||||
break;
|
||||
i2c_stop(bus);
|
||||
snooze(50);
|
||||
}
|
||||
|
||||
// TRACE("i2c_start_address: %s, ack %d, i %d\n", strerror(res), ack, i);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* write one byte and the ack/nack
|
||||
* return values:
|
||||
* B_OK => byte transmitted
|
||||
* B_ERROR => arbitration lost
|
||||
* B_TIMED_OUT => time out
|
||||
*/
|
||||
status_t
|
||||
i2c_writebyte(i2c_bus *bus, uint8 byte, int *ack)
|
||||
{
|
||||
int has_arbitration;
|
||||
|
||||
int i;
|
||||
has_arbitration = 1;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
int bit = (byte >> i) & 1;
|
||||
if (has_arbitration) {
|
||||
if (bit)
|
||||
set_sda_high(bus);
|
||||
else
|
||||
set_sda_low(bus);
|
||||
}
|
||||
if (set_scl_high(bus) != B_OK) {
|
||||
set_sda_high(bus); // avoid blocking the bus
|
||||
TRACE("i2c_writebyte timeout at bit %d\n", i);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
if (has_arbitration) {
|
||||
if (bit == 1 && 0 == bus->get_sda(bus->cookie)) {
|
||||
has_arbitration = 0;
|
||||
// TRACE("i2c_writebyte lost arbitration at bit %d\n", i);
|
||||
}
|
||||
}
|
||||
set_scl_low(bus);
|
||||
}
|
||||
set_sda_high(bus);
|
||||
if (set_scl_high(bus) != B_OK) {
|
||||
TRACE("i2c_writebyte timeout at ack\n");
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
*ack = 0 == bus->get_sda(bus->cookie);
|
||||
set_scl_low(bus);
|
||||
|
||||
return has_arbitration ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* read one byte, don't generate ack
|
||||
*/
|
||||
status_t
|
||||
i2c_readbyte(i2c_bus *bus, uint8 *pbyte)
|
||||
{
|
||||
int i;
|
||||
uint8 byte;
|
||||
|
||||
set_sda_high(bus);
|
||||
byte = 0;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
if (set_scl_high(bus) != B_OK) {
|
||||
TRACE("i2c_readbyte timeout at bit %d\n", i);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
byte = (byte << 1) | bus->get_sda(bus->cookie);
|
||||
set_scl_low(bus);
|
||||
}
|
||||
*pbyte = byte;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_read_unlocked(i2c_bus *bus, int address, void *data, int size)
|
||||
{
|
||||
status_t status;
|
||||
uint8 *bytes;
|
||||
|
||||
if (size <= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status = i2c_start_address(bus, address, 1 /* 1 = read, 0 = write */);
|
||||
if (status != B_OK) {
|
||||
TRACE("i2c_read: error on i2c_start_address: %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
bytes = data;
|
||||
while (size > 0) {
|
||||
if (i2c_readbyte(bus, bytes) != B_OK) { // timeout
|
||||
TRACE("i2c_read: timeout error on byte %ld\n", bytes - (uint8 *)data);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
if (size > 0)
|
||||
set_sda_low(bus); // ack
|
||||
else
|
||||
set_sda_high(bus); // nack
|
||||
|
||||
if (set_scl_high(bus) != B_OK) {
|
||||
set_sda_high(bus); // avoid blocking the bus
|
||||
TRACE("i2c_read: timeout at ack\n");
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
set_scl_low(bus);
|
||||
set_sda_high(bus);
|
||||
|
||||
size--;
|
||||
bytes++;
|
||||
}
|
||||
|
||||
i2c_stop(bus);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_write_unlocked(i2c_bus *bus, int address, const void *data, int size)
|
||||
{
|
||||
const uint8 *bytes;
|
||||
status_t status;
|
||||
int ack;
|
||||
|
||||
if (size <= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status = i2c_start_address(bus, address, 0 /* 1 = read, 0 = write */);
|
||||
if (status != B_OK) {
|
||||
TRACE("i2c_write: error on i2c_start_address: %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
bytes = data;
|
||||
while (size > 0) {
|
||||
status = i2c_writebyte(bus, *bytes, &ack);
|
||||
if (status == B_TIMED_OUT) {
|
||||
TRACE("i2c_write: timeout error on byte %ld\n", bytes - (uint8 *)data);
|
||||
return B_TIMED_OUT;
|
||||
}
|
||||
if (status != B_OK) {
|
||||
TRACE("i2c_write: arbitration lost on byte %ld\n", bytes - (uint8 *)data);
|
||||
break;
|
||||
}
|
||||
if (!ack) {
|
||||
TRACE("i2c_write: error, got NACK on byte %ld\n", bytes - (uint8 *)data);
|
||||
break;
|
||||
}
|
||||
bytes++;
|
||||
size--;
|
||||
}
|
||||
i2c_stop(bus);
|
||||
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return ack ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_read(i2c_bus *bus, int address, void *data, int size)
|
||||
{
|
||||
status_t res;
|
||||
acquire_sem(bus->sem);
|
||||
res = i2c_read_unlocked(bus, address, data, size);
|
||||
release_sem(bus->sem);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_write(i2c_bus *bus, int address, const void *data, int size)
|
||||
{
|
||||
status_t res;
|
||||
acquire_sem(bus->sem);
|
||||
res = i2c_write_unlocked(bus, address, data, size);
|
||||
release_sem(bus->sem);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
i2c_xfer(i2c_bus *bus, int address,
|
||||
const void *write_data, int write_size,
|
||||
void *read_data, int read_size)
|
||||
{
|
||||
status_t res;
|
||||
|
||||
acquire_sem(bus->sem);
|
||||
|
||||
if (write_data != 0 && write_size != 0) {
|
||||
res = i2c_write_unlocked(bus, address, write_data, write_size);
|
||||
if (res != B_OK) {
|
||||
release_sem(bus->sem);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_data != 0 && read_size != 0) {
|
||||
res = i2c_read_unlocked(bus, address, read_data, read_size);
|
||||
if (res != B_OK) {
|
||||
release_sem(bus->sem);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
release_sem(bus->sem);
|
||||
|
||||
return B_OK;
|
||||
}
|
55
src/add-ons/kernel/drivers/dvb/cx23882/i2c_core.h
Normal file
55
src/add-ons/kernel/drivers/dvb/cx23882/i2c_core.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __I2C_CORE_H
|
||||
#define __I2C_CORE_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
typedef void (*i2c_set_scl)(void *cookie, int state);
|
||||
typedef void (*i2c_set_sda)(void *cookie, int state);
|
||||
typedef int (*i2c_get_scl)(void *cookie);
|
||||
typedef int (*i2c_get_sda)(void *cookie);
|
||||
|
||||
struct _i2c_bus;
|
||||
typedef struct _i2c_bus i2c_bus;
|
||||
|
||||
i2c_bus *i2c_create_bus(void *cookie,
|
||||
int freqency,
|
||||
bigtime_t timeout,
|
||||
i2c_set_scl set_scl,
|
||||
i2c_set_sda set_sda,
|
||||
i2c_get_scl get_scl,
|
||||
i2c_get_sda get_sda);
|
||||
|
||||
void i2c_delete_bus(i2c_bus *bus);
|
||||
|
||||
status_t i2c_read(i2c_bus *bus, int address, void *data, int size);
|
||||
status_t i2c_write(i2c_bus *bus, int address, const void *data, int size);
|
||||
|
||||
status_t i2c_xfer(i2c_bus *bus, int address,
|
||||
const void *write_data, int write_size,
|
||||
void *read_data, int read_size);
|
||||
|
||||
#endif
|
95
src/add-ons/kernel/drivers/dvb/cx23882/util.c
Normal file
95
src/add-ons/kernel/drivers/dvb/cx23882/util.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <Errors.h>
|
||||
#include <OS.h>
|
||||
#include <string.h>
|
||||
#include "util.h"
|
||||
|
||||
#define TRACE_UTIL
|
||||
#ifdef TRACE_UTIL
|
||||
#define TRACE dprintf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
|
||||
area_id
|
||||
map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name)
|
||||
{
|
||||
uint32 offset;
|
||||
void *phyadr;
|
||||
void *mapadr;
|
||||
area_id area;
|
||||
|
||||
TRACE("mapping physical address %p with %ld bytes for %s\n", phy, size, name);
|
||||
|
||||
offset = (uint32)phy & (B_PAGE_SIZE - 1);
|
||||
phyadr = (char *)phy - offset;
|
||||
size = ROUNDUP(size + offset, B_PAGE_SIZE);
|
||||
area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr);
|
||||
if (area < B_OK) {
|
||||
TRACE("mapping '%s' failed, error 0x%lx (%s)\n", name, area, strerror(area));
|
||||
return area;
|
||||
}
|
||||
|
||||
*virt = (char *)mapadr + offset;
|
||||
|
||||
TRACE("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = %p, size = %ld, area = 0x%08lx\n",
|
||||
phy, *virt, offset, phyadr, mapadr, size, area);
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
area_id
|
||||
alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name)
|
||||
{
|
||||
physical_entry pe;
|
||||
void * virtadr;
|
||||
area_id areaid;
|
||||
status_t rv;
|
||||
|
||||
TRACE("allocating %ld bytes for %s\n", size, name);
|
||||
|
||||
size = ROUNDUP(size, B_PAGE_SIZE);
|
||||
areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK | B_CONTIGUOUS, protection);
|
||||
if (areaid < B_OK) {
|
||||
TRACE("couldn't allocate area %s\n", name);
|
||||
return B_ERROR;
|
||||
}
|
||||
rv = get_memory_map(virtadr, size, &pe, 1);
|
||||
if (rv < B_OK) {
|
||||
delete_area(areaid);
|
||||
TRACE("couldn't map %s\n", name);
|
||||
return B_ERROR;
|
||||
}
|
||||
if (virt)
|
||||
*virt = virtadr;
|
||||
if (phy)
|
||||
*phy = pe.address;
|
||||
TRACE("area = %ld, size = %ld, virt = %p, phy = %p\n", areaid, size, virtadr, pe.address);
|
||||
return areaid;
|
||||
}
|
38
src/add-ons/kernel/drivers/dvb/cx23882/util.h
Normal file
38
src/add-ons/kernel/drivers/dvb/cx23882/util.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_H
|
||||
#define __UTIL_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
area_id map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name);
|
||||
area_id alloc_mem(void **virt, void **phy, size_t size, uint32 protection, const char *name);
|
||||
|
||||
// generic macro for rounding, can only be used for power of 2 blocksize
|
||||
#define ROUNDUP(size, blocksize) (((size) + (blocksize) - 1) & ~((blocksize) - 1))
|
||||
|
||||
#define atomic_read(a) atomic_or(a, 0)
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user