Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. |
| 3 | * |
| 4 | * This source file is released under GPL v2 license (no other versions). |
| 5 | * See the COPYING file included in the main directory of this source |
| 6 | * distribution for the license terms and conditions. |
| 7 | * |
| 8 | * @File cthardware.c |
| 9 | * |
| 10 | * @Brief |
| 11 | * This file contains the implementation of hardware access methord. |
| 12 | * |
| 13 | * @Author Liu Chun |
| 14 | * @Date Jun 26 2008 |
| 15 | * |
| 16 | */ |
| 17 | |
| 18 | #include "cthardware.h" |
| 19 | #include "cthw20k1.h" |
| 20 | #include "cthw20k2.h" |
| 21 | #include <linux/bug.h> |
| 22 | |
Takashi Iwai | 9470195 | 2009-06-08 18:10:32 +0200 | [diff] [blame] | 23 | int __devinit create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type, |
| 24 | enum CTCARDS model, struct hw **rhw) |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 25 | { |
Takashi Iwai | 514eef9 | 2009-06-08 14:57:57 +0200 | [diff] [blame] | 26 | int err; |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 27 | |
Takashi Iwai | 9470195 | 2009-06-08 18:10:32 +0200 | [diff] [blame] | 28 | switch (chip_type) { |
| 29 | case ATC20K1: |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 30 | err = create_20k1_hw_obj(rhw); |
| 31 | break; |
Takashi Iwai | 9470195 | 2009-06-08 18:10:32 +0200 | [diff] [blame] | 32 | case ATC20K2: |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 33 | err = create_20k2_hw_obj(rhw); |
| 34 | break; |
| 35 | default: |
| 36 | err = -ENODEV; |
| 37 | break; |
| 38 | } |
| 39 | if (err) |
| 40 | return err; |
| 41 | |
| 42 | (*rhw)->pci = pci; |
Takashi Iwai | 9470195 | 2009-06-08 18:10:32 +0200 | [diff] [blame] | 43 | (*rhw)->chip_type = chip_type; |
| 44 | (*rhw)->model = model; |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 45 | |
| 46 | return 0; |
| 47 | } |
| 48 | |
| 49 | int destroy_hw_obj(struct hw *hw) |
| 50 | { |
Takashi Iwai | 514eef9 | 2009-06-08 14:57:57 +0200 | [diff] [blame] | 51 | int err; |
Wai Yew CHAY | 8cc7236 | 2009-05-14 08:05:58 +0200 | [diff] [blame] | 52 | |
| 53 | switch (hw->pci->device) { |
| 54 | case 0x0005: /* 20k1 device */ |
| 55 | err = destroy_20k1_hw_obj(hw); |
| 56 | break; |
| 57 | case 0x000B: /* 20k2 device */ |
| 58 | err = destroy_20k2_hw_obj(hw); |
| 59 | break; |
| 60 | default: |
| 61 | err = -ENODEV; |
| 62 | break; |
| 63 | } |
| 64 | |
| 65 | return err; |
| 66 | } |
| 67 | |
| 68 | unsigned int get_field(unsigned int data, unsigned int field) |
| 69 | { |
| 70 | int i; |
| 71 | |
| 72 | BUG_ON(!field); |
| 73 | /* @field should always be greater than 0 */ |
| 74 | for (i = 0; !(field & (1 << i)); ) |
| 75 | i++; |
| 76 | |
| 77 | return (data & field) >> i; |
| 78 | } |
| 79 | |
| 80 | void set_field(unsigned int *data, unsigned int field, unsigned int value) |
| 81 | { |
| 82 | int i; |
| 83 | |
| 84 | BUG_ON(!field); |
| 85 | /* @field should always be greater than 0 */ |
| 86 | for (i = 0; !(field & (1 << i)); ) |
| 87 | i++; |
| 88 | |
| 89 | *data = (*data & (~field)) | ((value << i) & field); |
| 90 | } |
| 91 | |