blob: 1d506448621785c7c48d6dc0644ddcb2c3c1315c [file] [log] [blame]
Thomas Gleixner5765e782019-05-31 01:09:25 -07001// SPDX-License-Identifier: GPL-2.0-only
Pierre-Louis Bossartfe372852020-07-02 14:35:50 -05002/*
Wai Yew CHAY8cc72362009-05-14 08:05:58 +02003 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
4 *
Wai Yew CHAY8cc72362009-05-14 08:05:58 +02005 * @File cthardware.c
6 *
7 * @Brief
8 * This file contains the implementation of hardware access methord.
9 *
10 * @Author Liu Chun
11 * @Date Jun 26 2008
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020012 */
13
14#include "cthardware.h"
15#include "cthw20k1.h"
16#include "cthw20k2.h"
17#include <linux/bug.h>
18
Bill Pembertone23e7a12012-12-06 12:35:10 -050019int create_hw_obj(struct pci_dev *pci, enum CHIPTYP chip_type,
20 enum CTCARDS model, struct hw **rhw)
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020021{
Takashi Iwai514eef92009-06-08 14:57:57 +020022 int err;
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020023
Takashi Iwai94701952009-06-08 18:10:32 +020024 switch (chip_type) {
25 case ATC20K1:
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020026 err = create_20k1_hw_obj(rhw);
27 break;
Takashi Iwai94701952009-06-08 18:10:32 +020028 case ATC20K2:
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020029 err = create_20k2_hw_obj(rhw);
30 break;
31 default:
32 err = -ENODEV;
33 break;
34 }
35 if (err)
36 return err;
37
38 (*rhw)->pci = pci;
Takashi Iwai94701952009-06-08 18:10:32 +020039 (*rhw)->chip_type = chip_type;
40 (*rhw)->model = model;
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020041
42 return 0;
43}
44
45int destroy_hw_obj(struct hw *hw)
46{
Takashi Iwai514eef92009-06-08 14:57:57 +020047 int err;
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020048
49 switch (hw->pci->device) {
50 case 0x0005: /* 20k1 device */
51 err = destroy_20k1_hw_obj(hw);
52 break;
53 case 0x000B: /* 20k2 device */
54 err = destroy_20k2_hw_obj(hw);
55 break;
56 default:
57 err = -ENODEV;
58 break;
59 }
60
61 return err;
62}
63
64unsigned int get_field(unsigned int data, unsigned int field)
65{
66 int i;
67
Takashi Iwai29fa9572013-11-05 15:00:02 +010068 if (WARN_ON(!field))
69 return 0;
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020070 /* @field should always be greater than 0 */
71 for (i = 0; !(field & (1 << i)); )
72 i++;
73
74 return (data & field) >> i;
75}
76
77void set_field(unsigned int *data, unsigned int field, unsigned int value)
78{
79 int i;
80
Takashi Iwai29fa9572013-11-05 15:00:02 +010081 if (WARN_ON(!field))
82 return;
Wai Yew CHAY8cc72362009-05-14 08:05:58 +020083 /* @field should always be greater than 0 */
84 for (i = 0; !(field & (1 << i)); )
85 i++;
86
87 *data = (*data & (~field)) | ((value << i) & field);
88}
89