2009-05-14 14:05:58 +08:00
|
|
|
/**
|
|
|
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* This source file is released under GPL v2 license (no other versions).
|
|
|
|
* See the COPYING file included in the main directory of this source
|
|
|
|
* distribution for the license terms and conditions.
|
|
|
|
*
|
|
|
|
* @File cthardware.c
|
|
|
|
*
|
|
|
|
* @Brief
|
|
|
|
* This file contains the implementation of hardware access methord.
|
|
|
|
*
|
|
|
|
* @Author Liu Chun
|
|
|
|
* @Date Jun 26 2008
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "cthardware.h"
|
|
|
|
#include "cthw20k1.h"
|
|
|
|
#include "cthw20k2.h"
|
|
|
|
#include <linux/bug.h>
|
|
|
|
|
2012-12-07 01:35:10 +08:00
|
|
|
int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
|
|
|
|
enum CTCARDS model, struct hw **rhw)
|
2009-05-14 14:05:58 +08:00
|
|
|
{
|
2009-06-08 20:57:57 +08:00
|
|
|
int err;
|
2009-05-14 14:05:58 +08:00
|
|
|
|
2009-06-09 00:10:32 +08:00
|
|
|
switch (chip_type) {
|
|
|
|
case ATC20K1:
|
2009-05-14 14:05:58 +08:00
|
|
|
err = create_20k1_hw_obj(rhw);
|
|
|
|
break;
|
2009-06-09 00:10:32 +08:00
|
|
|
case ATC20K2:
|
2009-05-14 14:05:58 +08:00
|
|
|
err = create_20k2_hw_obj(rhw);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
err = -ENODEV;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
(*rhw)->pci = pci;
|
2009-06-09 00:10:32 +08:00
|
|
|
(*rhw)->chip_type = chip_type;
|
|
|
|
(*rhw)->model = model;
|
2009-05-14 14:05:58 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int destroy_hw_obj(struct hw *hw)
|
|
|
|
{
|
2009-06-08 20:57:57 +08:00
|
|
|
int err;
|
2009-05-14 14:05:58 +08:00
|
|
|
|
|
|
|
switch (hw->pci->device) {
|
|
|
|
case 0x0005: /* 20k1 device */
|
|
|
|
err = destroy_20k1_hw_obj(hw);
|
|
|
|
break;
|
|
|
|
case 0x000B: /* 20k2 device */
|
|
|
|
err = destroy_20k2_hw_obj(hw);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
err = -ENODEV;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int get_field(unsigned int data, unsigned int field)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2013-11-05 22:00:02 +08:00
|
|
|
if (WARN_ON(!field))
|
|
|
|
return 0;
|
2009-05-14 14:05:58 +08:00
|
|
|
/* @field should always be greater than 0 */
|
|
|
|
for (i = 0; !(field & (1 << i)); )
|
|
|
|
i++;
|
|
|
|
|
|
|
|
return (data & field) >> i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_field(unsigned int *data, unsigned int field, unsigned int value)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2013-11-05 22:00:02 +08:00
|
|
|
if (WARN_ON(!field))
|
|
|
|
return;
|
2009-05-14 14:05:58 +08:00
|
|
|
/* @field should always be greater than 0 */
|
|
|
|
for (i = 0; !(field & (1 << i)); )
|
|
|
|
i++;
|
|
|
|
|
|
|
|
*data = (*data & (~field)) | ((value << i) & field);
|
|
|
|
}
|
|
|
|
|