linux-firmware: Add firmware patch for Intel Bluetooth 7265 ROM-spin(D0)
[platform/upstream/linux-firmware.git] / isci / create_fw.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <asm/types.h>
10 #include <strings.h>
11 #include <stdint.h>
12
13 #include "create_fw.h"
14
15 int write_blob(struct isci_orom *isci_orom)
16 {
17         FILE *fd;
18         int err;
19         size_t count;
20
21         fd = fopen(blob_name, "w+");
22         if (!fd) {
23                 perror("Open file for write failed");
24                 fclose(fd);
25                 return -EIO;
26         }
27
28         count = fwrite(isci_orom, sizeof(struct isci_orom), 1, fd);
29         if (count != 1) {
30                 perror("Write data failed");
31                 fclose(fd);
32                 return -EIO;
33         }
34
35         fclose(fd);
36
37         return 0;
38 }
39
40 void set_binary_values(struct isci_orom *isci_orom)
41 {
42         int c, phy_idx, port_idx;
43
44         /* setting OROM signature */
45         strncpy(isci_orom->hdr.signature, sig, strlen(sig));
46         isci_orom->hdr.version = version;
47         isci_orom->hdr.total_block_length = sizeof(struct isci_orom);
48         isci_orom->hdr.hdr_length = sizeof(struct sci_bios_oem_param_block_hdr);
49         isci_orom->hdr.num_elements = num_elements;
50
51         for (c = 0; c < 2; c++) {
52                 struct sci_oem_params *ctrl = &isci_orom->ctrl[c];
53                 __u8 cable_selection_mask = 0;
54
55                 ctrl->controller.mode_type = mode_type;
56                 ctrl->controller.max_concurr_spin_up = max_num_concurrent_dev_spin_up;
57                 ctrl->controller.do_enable_ssc = enable_ssc;
58
59                 for (port_idx = 0; port_idx < SCI_MAX_PORTS; port_idx++)
60                         ctrl->ports[port_idx].phy_mask = phy_mask[c][port_idx];
61
62                 for (phy_idx = 0; phy_idx < SCI_MAX_PHYS; phy_idx++) {
63                         struct sci_phy_oem_params *phy = &ctrl->phys[phy_idx];
64                         __u8 cable_phy = cable_selection[c][phy_idx];
65
66                         phy->sas_address.high = sas_addr[c][phy_idx] >> 32;
67                         phy->sas_address.low = sas_addr[c][phy_idx];
68
69                         phy->afe_tx_amp_control0 = afe_tx_amp_control0;
70                         phy->afe_tx_amp_control1 = afe_tx_amp_control1;
71                         phy->afe_tx_amp_control2 = afe_tx_amp_control2;
72                         phy->afe_tx_amp_control3 = afe_tx_amp_control3;
73
74                         cable_selection_mask |= (cable_phy & 1) << phy_idx;
75                         cable_selection_mask |= (cable_phy & 2) << (phy_idx + 3);
76                 }
77                 ctrl->controller.cable_selection_mask = cable_selection_mask;
78         }
79 }
80
81 int main(void)
82 {
83         int err;
84         struct isci_orom *isci_orom;
85
86         isci_orom = malloc(sizeof(struct isci_orom));
87         memset(isci_orom, 0, sizeof(struct isci_orom));
88
89         set_binary_values(isci_orom);
90
91         err = write_blob(isci_orom);
92         if (err < 0) {
93                 free(isci_orom);
94                 return err;
95         }
96
97         free(isci_orom);
98         return 0;
99 }